Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Appliquer les données de l'open data #3211

Merged
merged 22 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
431a34b
Remplace la liste déroulante des sources d'indicateur en composant Tabs
marc-rutkowski Apr 30, 2024
72c69cf
Renomme le sélecteur de la source d'un indicateur
marc-rutkowski Apr 30, 2024
7c5c5ad
Corrige une condition
marc-rutkowski Apr 30, 2024
2680c1a
Centralise le typage des sources open-data
marc-rutkowski May 2, 2024
37452ae
Ajoute le bandeau "appliquer à mes objectifs/résultats"
marc-rutkowski May 2, 2024
12d92dc
Ajoute le dialogue de résolution des conflits lors de l'application d…
marc-rutkowski May 7, 2024
925a5b4
Ajoute les fonctions pour appliquer des données open-data aux objecti…
marc-rutkowski May 7, 2024
ea02964
Répare les imports
marc-rutkowski May 7, 2024
9d2bc62
Raccorde la modale et la fonction d'application des données externes
marc-rutkowski May 7, 2024
d1741ac
Force l'affichage de l'onglet Résultats sil il n'y a pas d'onglet Obj…
marc-rutkowski May 14, 2024
5572cb7
Ajooute une option pour désactiver le chargement auto des valeurs d'i…
marc-rutkowski May 14, 2024
1b4eae8
Enregistre le champ `source` quand il est disponible en commentaire d…
marc-rutkowski May 14, 2024
ed22d52
Change un libellé
marc-rutkowski May 14, 2024
b2fe613
Met à jour les storyshots
marc-rutkowski May 14, 2024
ba12ac0
Ajoute des commentaires
marc-rutkowski May 16, 2024
45ddca3
Ajoute les définitions pour le tracking de l'application des sources …
marc-rutkowski May 16, 2024
166697a
Ajoute le tracking de l'application des sources open data
marc-rutkowski May 16, 2024
3aad4d1
Met à jour les storyshots
marc-rutkowski May 16, 2024
6d80524
Fixe un test
marc-rutkowski May 16, 2024
10c1439
Change un typage et déplace une condition
marc-rutkowski May 21, 2024
d3baf72
Enlève une condition inutile
marc-rutkowski May 21, 2024
1a80784
Simplifie et répare une condition
marc-rutkowski May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api_tests/tests/indicateurs/filtre.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const expectations: {
filter: {
collectivite_id: 1,
},
count: 200, // 199 indicateurs prédéfinis + 1 perso
count: 202, // 201 indicateurs prédéfinis + 1 perso
examples: [
{
collectivite_id: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {IndicateurSidePanelToolbar} from './IndicateurSidePanelToolbar';
import {TIndicateurPredefini} from './types';
import {useExportIndicateurs} from './useExportIndicateurs';
import {useIndicateurPredefini} from './useIndicateurDefinition';
import {TrackPageView} from '@tet/ui';
import {useCollectiviteId} from 'core-logic/hooks/params';

/** Charge et affiche le détail d'un indicateur prédéfini et de ses éventuels "enfants" */
export const IndicateurPredefiniBase = ({
Expand All @@ -18,8 +20,14 @@ export const IndicateurPredefiniBase = ({
definition,
]);

const collectivite_id = useCollectiviteId()!;

return (
<>
<TrackPageView
pageName="app/indicateurs/predefini"
properties={{collectivite_id, indicateur_id: definition.id}}
/>
<HeaderIndicateur title={definition.nom} />
<div className="px-10 py-4">
<div className="flex flex-row justify-end fr-mb-2w">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {SourceType} from './types';

export const SOURCE_TYPE_LABEL: Record<SourceType, string> = {
objectif: 'objectifs',
resultat: 'résultats',
};

export const getSourceTypeLabel = (sourceType: SourceType | null) =>
(sourceType && SOURCE_TYPE_LABEL[sourceType]) || null;

export const SOURCE_COLLECTIVITE = '$sc';
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from 'react';
import {Meta} from '@storybook/react';
import {action} from '@storybook/addon-actions';
import {ApplyOpenDataModal, Props} from './ApplyOpenDataModal';

export default {
component: ApplyOpenDataModal,
args: {
setOverwrite: action('setOverwrite'),
},
render: args => (
<div className="flex flex-col gap-8">
<ApplyOpenDataModal {...args} />
</div>
),
} as Meta<Props>;

export const AvecConflits = {
args: {
definition: {unite: 'teqCO2'},
source: {id: 'pcaet', nom: 'PCAET', type: 'objectif'},
comparaison: {
conflits: 2,
lignes: [
{annee: 2022, valeur: 141_299, nouvelleValeur: 150_000, conflit: true},
{annee: 2021, valeur: 141_299, nouvelleValeur: 140_000, conflit: true},
],
},
},
};

export const AvecConflitsEcrasement = {
args: {...AvecConflits.args, overwrite: true},
};

export const SansConflits = {
args: {
definition: {unite: 'teqCO2'},
source: {id: 'pcaet', nom: 'PCAET', type: 'objectif'},
comparaison: {
conflits: 0,
lignes: [
{
annee: 2022,
nouvelleValeur: 141_299,
conflit: false,
estNouveau: true,
},
{annee: 2021, valeur: 141_299, nouvelleValeur: 141_299, conflit: false},
],
},
},
};

export const EnConflitPartiel = {
args: {
definition: {unite: 'teqCO2'},
source: {id: 'pcaet', nom: 'PCAET', type: 'objectif'},
comparaison: {
conflits: 1,
lignes: [
{annee: 2022, valeur: 141_299, nouvelleValeur: 150_000, conflit: true},
{annee: 2021, valeur: 141_299, nouvelleValeur: 141_299, conflit: false},
],
},
},
};

export const EnConflitPartielEcrasement = {
args: {...EnConflitPartiel.args, overwrite: true},
};

export const VarianteResultats = {
args: {
definition: {unite: 'teqCO2'},
source: {id: 'pcaet', nom: 'PCAET', type: 'resultat'},
comparaison: {
conflits: 1,
lignes: [
{annee: 2022, valeur: 141_299, nouvelleValeur: 150_000, conflit: true},
{annee: 2021, valeur: 141_299, nouvelleValeur: 141_299, conflit: false},
],
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import {Alert, Checkbox} from '@tet/ui';
import {OpenDataComparaison} from './useApplyOpenData';
import {SourceType, TIndicateurDefinition} from '../types';
import {SOURCE_TYPE_LABEL} from '../constants';
import classNames from 'classnames';

export type Props = {
/** Indicateur concerné */
definition: TIndicateurDefinition;
/** Comparaison entre les données de la collectivité et celles à appliquer */
comparaison: OpenDataComparaison;
/** Informations sur la source de données à appliquer */
source: {
type: SourceType;
id: string;
nom: string;
};
/** Indique si les données en conflit doivent être écrasées */
overwrite: boolean;
/** Appeler pour changer le flag indiquant si les données en conflit doivent être écrasées */
setOverwrite: (value: boolean) => void;
};

// pour formater les chiffres
const NumFormat = Intl.NumberFormat('fr', {maximumFractionDigits: 3});

/**
* Affiche le contenu de la modale de confirmation avant écrasement des données
* utilisateur par les données importées.
*/
export const ApplyOpenDataModal = ({
definition,
comparaison,
source,
overwrite,
setOverwrite,
}: Props) => {
if (!comparaison || !source || !definition) return;

const {lignes, conflits} = comparaison;
const {type, nom} = source;
const sourceType = SOURCE_TYPE_LABEL[type];

return (
<>
{!!conflits && (
<>
<Alert
state="warning"
title="Conflit détecté"
description={`Vous êtes sur le point d’appliquer les « ${sourceType} ${nom} » à vos ${sourceType}.
Attention : certaines données des « ${sourceType} ${nom} » entrent en conflit avec vos ${sourceType} et ont des valeurs différentes.`}
/>
<Checkbox
id="replace-data"
label={`Remplacer mes ${sourceType} en cours par les ${sourceType} ${nom}`}
checked={overwrite}
onChange={() => setOverwrite(!overwrite)}
/>
</>
)}
<div className="flex flex-wrap gap-4 w-full">
<table className="fr-table fr-table--bordered grow md:max-w-[calc(68%-1rem)]">
<thead>
<tr>
<th scope="col" className="whitespace-break-spaces">
Date{`\n`}
</th>
<th scope="col">
Mes {sourceType}
<span className="font-normal"> ({definition.unite})</span>
</th>
<th scope="col">
<span className="capitalize">{sourceType}</span> {nom}
<span className="font-normal"> ({definition.unite})</span>
</th>
</tr>
</thead>
<tbody>
{lignes.map(({annee, valeur, nouvelleValeur, conflit}) => (
<tr key={annee}>
<td>{annee}</td>
<td
className={classNames({
'line-through': conflit && overwrite,
})}
>
{valeur === null || isNaN(valeur)
? ''
: NumFormat.format(valeur)}
</td>
<td>{NumFormat.format(nouvelleValeur ?? valeur)}</td>
</tr>
))}
</tbody>
</table>
<table className="fr-table fr-table--bordered fr-table--blue-ecume md:max-w-[32%]">
<thead>
<tr>
<th className="whitespace-break-spaces !text-center !px-8 !py-[0.31rem]">
Après validation{`\n`}
<span className="capitalize">
{sourceType} {nom}
</span>
<span className="font-normal"> ({definition.unite})</span>
</th>
</tr>
</thead>
<tbody>
{lignes.map(({annee, valeur, nouvelleValeur, conflit}) => {
const v = !conflit || overwrite ? nouvelleValeur : valeur;
return (
<tr key={annee}>
<td>{isNaN(v) ? <>&nbsp;</> : NumFormat.format(v)}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</>
);
};

This file was deleted.

Loading
Loading