From 431a34b1c15d7c2bb61e5bbc6175819faa63124f Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 30 Apr 2024 16:47:43 +0200 Subject: [PATCH 01/22] =?UTF-8?q?Remplace=20la=20liste=20d=C3=A9roulante?= =?UTF-8?q?=20des=20sources=20d'indicateur=20en=20composant=20Tabs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/ImportSourcesDropdown.tsx | 55 +++++++++++++------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesDropdown.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesDropdown.tsx index c3ae9e09b7..a295bf89d7 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesDropdown.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesDropdown.tsx @@ -1,10 +1,8 @@ -import FormField from 'ui/shared/form/FormField'; import {IndicateurImportSource, SOURCE_COLLECTIVITE} from './useImportSources'; -import SelectDropdown from 'ui/shared/select/SelectDropdown'; -import {DSFRbuttonClassname} from 'ui/shared/select/commons'; +import {Tab, Tabs} from '@tet/ui'; /** - * Affiche la liste déroulante des sources de données d'un indicateur, lorsqu'il + * Affiche le sélecteur des sources de données d'un indicateur, lorsqu'il * y en a plusieurs. Sinon rien n'est affiché. */ export const ImportSourcesDropdown = ({ @@ -16,17 +14,42 @@ export const ImportSourcesDropdown = ({ currentSource: string; setCurrentSource?: (value: string) => void; }) => { - return sources?.length && setCurrentSource ? ( - - ({label: libelle, value: id})), - ]} - value={currentSource} - onSelect={setCurrentSource} - /> - + const {indexedSources, idToIndex, indexToId} = useIndexedSources(sources); + + return indexedSources && setCurrentSource ? ( + setCurrentSource(indexToId(activeTab))} + > + {indexedSources?.map(({id, libelle}) => ( + + ))} + ) : null; }; + +/** + * Ajoute la source "mes données" à l'index 0 et renvoi des fonctions + * utilitaires pour transformer les id en index et réciproquement. + */ +const useIndexedSources = (sources?: IndicateurImportSource[] | null) => { + // ajoute la source "mes données" + const indexedSources = sources?.length + ? [{id: SOURCE_COLLECTIVITE, libelle: 'Mes données'}, ...sources] + : null; + + // converti un id de source en index + const idToIndex = (id: string) => + id === SOURCE_COLLECTIVITE + ? 0 + : indexedSources?.findIndex(s => s.id === id) ?? 0; + + // converti un index en id de source + const indexToId = (index: number) => + index === 0 + ? SOURCE_COLLECTIVITE + : indexedSources?.[index]?.id ?? SOURCE_COLLECTIVITE; + + return {indexedSources, idToIndex, indexToId}; +}; From 72c69cf277a41b9988fa35ccfcc6ce71b65ab402 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 30 Apr 2024 16:49:37 +0200 Subject: [PATCH 02/22] =?UTF-8?q?Renomme=20le=20s=C3=A9lecteur=20de=20la?= =?UTF-8?q?=20source=20d'un=20indicateur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ImportSourcesDropdown.tsx => ImportSourcesSelector.tsx} | 2 +- .../collectivite/Indicateurs/detail/IndicateurDetail.tsx | 4 ++-- .../Indicateurs/detail/IndicateurEnfantContent.tsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/{ImportSourcesDropdown.tsx => ImportSourcesSelector.tsx} (97%) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesDropdown.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx similarity index 97% rename from app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesDropdown.tsx rename to app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index a295bf89d7..67c4bd1b4d 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesDropdown.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -5,7 +5,7 @@ import {Tab, Tabs} from '@tet/ui'; * Affiche le sélecteur des sources de données d'un indicateur, lorsqu'il * y en a plusieurs. Sinon rien n'est affiché. */ -export const ImportSourcesDropdown = ({ +export const ImportSourcesSelector = ({ sources, currentSource, setCurrentSource, diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx index 2cfac01491..527e40e8e4 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx @@ -8,7 +8,7 @@ import {TIndicateurPredefini} from '../types'; import {FichesActionLiees} from '../FichesActionLiees'; import {IndicateurInfoLiees} from './IndicateurInfoLiees'; import {useIndicateurImportSources} from './useImportSources'; -import {ImportSourcesDropdown} from './ImportSourcesDropdown'; +import {ImportSourcesSelector} from './ImportSourcesSelector'; import IndicateurDetailChart from 'app/pages/collectivite/Indicateurs/detail/IndicateurDetailChart'; @@ -26,7 +26,7 @@ export const IndicateurDetail = ({ return ( <> - - Date: Tue, 30 Apr 2024 17:59:14 +0200 Subject: [PATCH 03/22] Corrige une condition --- .../Indicateurs/detail/ImportSourcesSelector.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index 67c4bd1b4d..f601695a89 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -40,10 +40,13 @@ const useIndexedSources = (sources?: IndicateurImportSource[] | null) => { : null; // converti un id de source en index - const idToIndex = (id: string) => - id === SOURCE_COLLECTIVITE - ? 0 - : indexedSources?.findIndex(s => s.id === id) ?? 0; + const idToIndex = (id: string) => { + if (id === SOURCE_COLLECTIVITE) { + return 0; + } + const index = indexedSources?.findIndex(s => s.id === id); + return index === -1 || index === undefined ? 0 : index; + }; // converti un index en id de source const indexToId = (index: number) => From 2680c1af30752badfc54395ad5a16005d3bebe30 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Thu, 2 May 2024 11:40:40 +0200 Subject: [PATCH 04/22] Centralise le typage des sources open-data --- .../Indicateurs/detail/ImportSourcesSelector.tsx | 3 +-- .../Indicateurs/detail/IndicateurValuesTable.tsx | 7 +++---- .../Indicateurs/detail/useEditIndicateurValeur.ts | 14 ++++++++------ .../Indicateurs/detail/useImportSources.ts | 4 ++-- .../app/pages/collectivite/Indicateurs/types.ts | 5 +++++ .../Indicateurs/useIndicateurValeurs.ts | 9 +++------ 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index f601695a89..9270f84e0e 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -1,5 +1,4 @@ -import {IndicateurImportSource, SOURCE_COLLECTIVITE} from './useImportSources'; -import {Tab, Tabs} from '@tet/ui'; +import {SOURCE_COLLECTIVITE} from '../types'; /** * Affiche le sélecteur des sources de données d'un indicateur, lorsqu'il diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx index 759c250c4e..78b9a4cc97 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx @@ -1,5 +1,6 @@ +import {useEffect, useState} from 'react'; import classNames from 'classnames'; -import {TIndicateurDefinition} from '../types'; +import {TIndicateurDefinition, SOURCE_COLLECTIVITE, SourceType} from '../types'; import { TIndicateurValeurEtCommentaires, useIndicateurValeursEtCommentaires, @@ -14,12 +15,10 @@ import { ValueTableRowReadOnly, IndicateurValueTableRow, } from './IndicateurValueTableRow'; -import {useEffect, useState} from 'react'; -import {SOURCE_COLLECTIVITE} from './useImportSources'; type IndicateurValuesTableProps = { definition: TIndicateurDefinition; - type: 'resultat' | 'objectif'; + type: SourceType; importSource?: string; isReadonly: boolean; confidentiel?: boolean; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useEditIndicateurValeur.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useEditIndicateurValeur.ts index e3aa9d1bc8..d44db27d37 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useEditIndicateurValeur.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useEditIndicateurValeur.ts @@ -1,14 +1,16 @@ import {useMutation, useQueryClient} from 'react-query'; import {supabaseClient} from 'core-logic/api/supabase'; import {useCollectiviteId} from 'core-logic/hooks/params'; -import {TIndicateurDefinition, TIndicateurPredefini} from '../types'; - -type TypeValeur = 'resultat' | 'objectif'; +import { + SourceType, + TIndicateurDefinition, + TIndicateurPredefini, +} from '../types'; type TEditIndicateurValeurArgs = { collectivite_id: number | null; definition: TIndicateurDefinition; - type: TypeValeur; + type: SourceType; }; /** Fourni des fonctions pour éditer ou "supprimer" une valeur/commentaire d'un indicateur */ @@ -33,11 +35,11 @@ export type TEditIndicateurValeurHandlers = ReturnType< >; // où écrire en fonction du type de valeur et si c'est un indicateur personnalisé ou non -const tableValeur = (type: TypeValeur, isPerso?: boolean) => +const tableValeur = (type: SourceType, isPerso?: boolean) => isPerso ? (`indicateur_personnalise_${type}` as const) : (`indicateur_${type}` as const); -const tableCommentaire = (type: TypeValeur, isPerso?: boolean) => +const tableCommentaire = (type: SourceType, isPerso?: boolean) => isPerso ? (`indicateur_perso_${type}_commentaire` as const) : (`indicateur_${type}_commentaire` as const); diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts index 85be300972..2cafead8e9 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts @@ -3,12 +3,12 @@ import {useQuery} from 'react-query'; import {supabaseClient} from 'core-logic/api/supabase'; import {useCollectiviteId} from 'core-logic/hooks/params'; import {naturalSort} from 'utils/naturalSort'; - -export const SOURCE_COLLECTIVITE = '$sc'; +import {SOURCE_COLLECTIVITE, SourceType} from '../types'; export type IndicateurImportSource = { id: string; libelle: string; + type?: SourceType; }; /** diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts index df8e41f8fe..0336ea5553 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts @@ -8,6 +8,11 @@ type Thematique = { nom: string; }; +export const SOURCE_COLLECTIVITE = '$sc'; + +/** type de données importées */ +export type SourceType = 'resultat' | 'objectif'; + /** Item dans une liste d'indicateurs (avant que le détail pour la vignette ne soit chargé) */ export type TIndicateurListItem = { id: string | number; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts index c6471fcf0c..3bdfd10a35 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts @@ -2,11 +2,8 @@ import {useQuery} from 'react-query'; import {DISABLE_AUTO_REFETCH, supabaseClient} from 'core-logic/api/supabase'; import {useCollectiviteId} from 'core-logic/hooks/params'; import {Enums} from '@tet/api'; -import {TIndicateurDefinition} from './types'; -import { - SOURCE_COLLECTIVITE, - useIndicateurImportSources, -} from './detail/useImportSources'; +import {SOURCE_COLLECTIVITE, SourceType, TIndicateurDefinition} from './types'; +import {useIndicateurImportSources} from './detail/useImportSources'; export type TIndicateurValeur = { annee: number; @@ -76,7 +73,7 @@ export const useIndicateurValeursEtCommentaires = ({ importSource, }: { definition: TIndicateurDefinition; - type: 'resultat' | 'objectif'; + type: SourceType; importSource?: string; }) => { const {id, isPerso} = definition; From 37452ae1dc3a1a6778a2e3e03fe8fed88ded5d02 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Thu, 2 May 2024 11:42:23 +0200 Subject: [PATCH 05/22] =?UTF-8?q?Ajoute=20le=20bandeau=20"appliquer=20?= =?UTF-8?q?=C3=A0=20mes=20objectifs/r=C3=A9sultats"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/ImportSourcesSelector.tsx | 62 +++++++++++++++---- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index 9270f84e0e..559a1a6064 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -1,4 +1,14 @@ -import {SOURCE_COLLECTIVITE} from '../types'; +import {Alert, Button, Tab, Tabs} from '@tet/ui'; +import {SOURCE_COLLECTIVITE, SourceType} from '../types'; +import {IndicateurImportSource} from './useImportSources'; + +const SOURCE_TYPE_LABEL: Record = { + objectif: 'objectifs', + resultat: 'résultats', +}; + +const getSourceTypeLabel = (sourceType: SourceType | null) => + (sourceType && SOURCE_TYPE_LABEL[sourceType]) || null; /** * Affiche le sélecteur des sources de données d'un indicateur, lorsqu'il @@ -13,18 +23,37 @@ export const ImportSourcesSelector = ({ currentSource: string; setCurrentSource?: (value: string) => void; }) => { - const {indexedSources, idToIndex, indexToId} = useIndexedSources(sources); + const {indexedSources, idToIndex, indexToId, getSourceType} = + useIndexedSources(sources); + const sourceTypeLabel = getSourceTypeLabel(getSourceType(currentSource)); return indexedSources && setCurrentSource ? ( - setCurrentSource(indexToId(activeTab))} - > - {indexedSources?.map(({id, libelle}) => ( - - ))} - + <> + setCurrentSource(indexToId(activeTab))} + > + {indexedSources?.map(({id, libelle}) => ( + + ))} + + {currentSource !== SOURCE_COLLECTIVITE && sourceTypeLabel && ( + Appliquer à mes {sourceTypeLabel}} + /> + )} + ) : null; }; @@ -53,5 +82,14 @@ const useIndexedSources = (sources?: IndicateurImportSource[] | null) => { ? SOURCE_COLLECTIVITE : indexedSources?.[index]?.id ?? SOURCE_COLLECTIVITE; - return {indexedSources, idToIndex, indexToId}; + // donne le type d'une source + const getSourceType = (id: string) => { + if (id === SOURCE_COLLECTIVITE) { + return null; + } + const index = idToIndex(id); + return indexedSources?.[index]?.type || 'resultat'; + }; + + return {indexedSources, idToIndex, indexToId, getSourceType}; }; From 12d92dce6759e4130e3d9cee9320b51fef389b48 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 7 May 2024 18:00:47 +0200 Subject: [PATCH 06/22] =?UTF-8?q?Ajoute=20le=20dialogue=20de=20r=C3=A9solu?= =?UTF-8?q?tion=20des=20conflits=20lors=20de=20l'application=20des=20donn?= =?UTF-8?q?=C3=A9es=20externes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collectivite/Indicateurs/constants.tsx | 11 + .../detail/ApplyOpenDataModal.stories.tsx | 85 ++ .../Indicateurs/detail/ApplyOpenDataModal.tsx | 123 +++ .../ApplyOpenDataModal.stories.storyshot | 799 ++++++++++++++++++ .../pages/collectivite/Indicateurs/types.ts | 2 - 5 files changed, 1018 insertions(+), 2 deletions(-) create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/constants.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.stories.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/constants.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/constants.tsx new file mode 100644 index 0000000000..f5af9ef1d7 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/constants.tsx @@ -0,0 +1,11 @@ +import {SourceType} from './types'; + +export const SOURCE_TYPE_LABEL: Record = { + objectif: 'objectifs', + resultat: 'résultats', +}; + +export const getSourceTypeLabel = (sourceType: SourceType | null) => + (sourceType && SOURCE_TYPE_LABEL[sourceType]) || null; + +export const SOURCE_COLLECTIVITE = '$sc'; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.stories.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.stories.tsx new file mode 100644 index 0000000000..6f3982bd49 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.stories.tsx @@ -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 => ( +
+ +
+ ), +} as Meta; + +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}, + ], + }, + }, +}; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.tsx new file mode 100644 index 0000000000..848fad5700 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal.tsx @@ -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 && ( + <> + + setOverwrite(!overwrite)} + /> + + )} +
+ + + + + + + + + + {lignes.map(({annee, valeur, nouvelleValeur, conflit}) => ( + + + + + + ))} + +
+ Date{`\n`} + + Mes {sourceType} + ({definition.unite}) + + {sourceType} {nom} + ({definition.unite}) +
{annee} + {valeur === null || isNaN(valeur) + ? '' + : NumFormat.format(valeur)} + {NumFormat.format(nouvelleValeur ?? valeur)}
+ + + + + + + + {lignes.map(({annee, valeur, nouvelleValeur, conflit}) => { + const v = !conflit || overwrite ? nouvelleValeur : valeur; + return ( + + + + ); + })} + +
+ Après validation{`\n`} + + {sourceType} {nom} + + ({definition.unite}) +
{isNaN(v) ? <>  : NumFormat.format(v)}
+
+ + ); +}; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot new file mode 100644 index 0000000000..ea7a54b63a --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot @@ -0,0 +1,799 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal Avec Conflits 1`] = ` +
+
+ +
+
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
+
+
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ Date + + + + Mes + objectifs + + ( + teqCO2 + ) + + + + objectifs + + + PCAET + + ( + teqCO2 + ) + +
+ 2022 + + 141 299 + + 150 000 +
+ 2021 + + 141 299 + + 140 000 +
+ + + + + + + + + + + + + + +
+ Après validation + + + + objectifs + + PCAET + + + ( + teqCO2 + ) + +
+ 141 299 +
+ 141 299 +
+
+
+`; + +exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal Avec Conflits Ecrasement 1`] = ` +
+
+ +
+
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
+
+
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ Date + + + + Mes + objectifs + + ( + teqCO2 + ) + + + + objectifs + + + PCAET + + ( + teqCO2 + ) + +
+ 2022 + + 141 299 + + 150 000 +
+ 2021 + + 141 299 + + 140 000 +
+ + + + + + + + + + + + + + +
+ Après validation + + + + objectifs + + PCAET + + + ( + teqCO2 + ) + +
+ 150 000 +
+ 140 000 +
+
+
+`; + +exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal En Conflit Partiel 1`] = ` +
+
+ +
+
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
+
+
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ Date + + + + Mes + objectifs + + ( + teqCO2 + ) + + + + objectifs + + + PCAET + + ( + teqCO2 + ) + +
+ 2022 + + 141 299 + + 150 000 +
+ 2021 + + 141 299 + + 141 299 +
+ + + + + + + + + + + + + + +
+ Après validation + + + + objectifs + + PCAET + + + ( + teqCO2 + ) + +
+ 141 299 +
+ 141 299 +
+
+
+`; + +exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal Sans Conflits 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + +
+ Date + + + + Mes + objectifs + + ( + teqCO2 + ) + + + + objectifs + + + PCAET + + ( + teqCO2 + ) + +
+ 2022 + + + 141 299 +
+ 2021 + + 141 299 + + 141 299 +
+ + + + + + + + + + + + + + +
+ Après validation + + + + objectifs + + PCAET + + + ( + teqCO2 + ) + +
+ 141 299 +
+ 141 299 +
+
+
+`; + +exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal Variante Resultats 1`] = ` +
+
+ +
+
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « résultats PCAET » à vos résultats. Attention : certaines données des « résultats PCAET » entrent en conflit avec vos résultats et ont des valeurs différentes. +
+
+
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ Date + + + + Mes + résultats + + ( + teqCO2 + ) + + + + résultats + + + PCAET + + ( + teqCO2 + ) + +
+ 2022 + + 141 299 + + 150 000 +
+ 2021 + + 141 299 + + 141 299 +
+ + + + + + + + + + + + + + +
+ Après validation + + + + résultats + + PCAET + + + ( + teqCO2 + ) + +
+ 141 299 +
+ 141 299 +
+
+
+`; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts index 0336ea5553..9e72405bf4 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/types.ts @@ -8,8 +8,6 @@ type Thematique = { nom: string; }; -export const SOURCE_COLLECTIVITE = '$sc'; - /** type de données importées */ export type SourceType = 'resultat' | 'objectif'; From 925a5b49bab75f8a5102550bd2da776823480fdf Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 7 May 2024 18:01:07 +0200 Subject: [PATCH 07/22] =?UTF-8?q?Ajoute=20les=20fonctions=20pour=20appliqu?= =?UTF-8?q?er=20des=20donn=C3=A9es=20open-data=20aux=20objectifs=20et=20r?= =?UTF-8?q?=C3=A9sultats=20d'une=20collectivit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Indicateurs/detail/useApplyOpenData.ts | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts new file mode 100644 index 0000000000..0981adc21a --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts @@ -0,0 +1,148 @@ +/** + * Utilitaires pour appliquer des données open-data aux objectifs et résultats d'une collectivité + */ + +import {useMutation} from 'react-query'; +import {supabaseClient} from 'core-logic/api/supabase'; +import {TIndicateurValeur, useIndicateurValeurs} from '../useIndicateurValeurs'; +import {SourceType, TIndicateurDefinition} from '../types'; +import {SOURCE_TYPE_LABEL} from '../constants'; +import {useOnSuccess} from './useEditIndicateurValeur'; + +/** + * Compare les données actuelles et les données importées + */ +export const compareOpenData = ( + /** données actuelles */ + currentData: TIndicateurValeur[], + /** données à appliquer */ + openData: TIndicateurValeur[] +) => { + if (!openData?.length) { + // rien à appliquer + return null; + } + + // pour compter les lignes en conflit + let conflits = 0; + // et celles à insérer + let ajouts = 0; + + // parcours chaque ligne à appliquer + const lignes = openData.map(({annee, valeur}) => { + // cherche si une valeur a déjà été saisie pour la même année + const existingData = currentData?.find(d => d.annee === annee); + + // si pas de valeur pré-existante ou valeur identique => pas de conflit + if (!existingData || existingData.valeur === valeur) { + if (!existingData) { + // si la donnée n'existe pas encore c'est un ajout + ajouts++; + } + return { + conflit: false as const, + annee, + valeur: existingData?.valeur ?? null, + nouvelleValeur: valeur, + }; + } + + // sinon, la donnée est en conflit avec la valeur existante + conflits++; + return { + conflit: true as const, + annee, + valeur: existingData.valeur, + nouvelleValeur: valeur, + }; + }); + + // renvoi le nombre et le détail des conflits relevés + return { + lignes, + conflits, + ajouts, + }; +}; + +export type OpenDataComparaison = ReturnType; + +/** + * Applique les changements + */ +type UseApplyOpenDataArgs = { + collectivite_id: number | null; + definition: TIndicateurDefinition; + source?: {id: string; nom: string; type: SourceType}; +}; + +export const useApplyOpenData = ({ + collectivite_id, + definition, + source, +}: UseApplyOpenDataArgs) => { + return useMutation( + async ({ + comparaison, + overwrite, + }: { + comparaison: OpenDataComparaison; + overwrite: boolean; + }) => { + if (!source || !collectivite_id) return null; + + // filtre si nécessaire les lignes en conflit avec les données existantes + const filteredData = overwrite + ? comparaison?.lignes + : comparaison?.lignes?.filter(c => !c.conflit); + + // prépare les lignes à mettre à jour + const toUpsert = filteredData?.map(({annee, nouvelleValeur}) => ({ + annee, + valeur: nouvelleValeur, + collectivite_id, + indicateur_id: definition.id as string, + })); + if (!toUpsert?.length) return false; + + // enregistre les changements + // TODO: à changer quand le modèle aura changé + const table = `indicateur_${source.type}` as const; + return supabaseClient.from(table).upsert(toUpsert); + }, + { + mutationKey: 'apply_open_data', + meta: { + success: + source && + `Les ${SOURCE_TYPE_LABEL[source.type]} ${ + source.nom + } ont bien été appliqués`, + }, + onSuccess: useOnSuccess({ + collectivite_id, + definition, + type: source?.type || 'resultat', + }), + } + ); +}; + +/** + * Charge les données et fait la comparaison + */ +export const useOpenDataComparaison = ({ + definition, + importSource, +}: { + definition: TIndicateurDefinition; + importSource: string; +}) => { + const {data: currentData} = useIndicateurValeurs({id: definition.id}); + const {data: openData} = useIndicateurValeurs({ + id: definition.id, + importSource, + enabled: !!importSource, + }); + return compareOpenData(currentData || [], openData || []); +}; From ea029643f587153e0f78f6cb74c812ca3800a7fb Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 7 May 2024 18:02:20 +0200 Subject: [PATCH 08/22] =?UTF-8?q?R=C3=A9pare=20les=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collectivite/Indicateurs/detail/IndicateurValuesTable.tsx | 3 ++- .../collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx | 2 +- .../pages/collectivite/Indicateurs/detail/useImportSources.ts | 3 ++- .../app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx index 78b9a4cc97..96237553dd 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx @@ -1,6 +1,7 @@ import {useEffect, useState} from 'react'; import classNames from 'classnames'; -import {TIndicateurDefinition, SOURCE_COLLECTIVITE, SourceType} from '../types'; +import {TIndicateurDefinition, SourceType} from '../types'; +import {SOURCE_COLLECTIVITE} from '../constants'; import { TIndicateurValeurEtCommentaires, useIndicateurValeursEtCommentaires, diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx index 2be4f8f34a..029388a8ee 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx @@ -2,9 +2,9 @@ import {Tab, Tabs, useActiveTab} from 'ui/shared/Tabs'; import ToggleButton from 'ui/shared/designSystem/ToggleButton'; import DSTetTooltip from 'ui/shared/floating-ui/DSTetTooltip'; import {TIndicateurDefinition} from '../types'; +import {SOURCE_COLLECTIVITE} from '../constants'; import {useCurrentCollectivite} from 'core-logic/hooks/useCurrentCollectivite'; import {IndicateurValuesTable} from './IndicateurValuesTable'; -import {SOURCE_COLLECTIVITE} from './useImportSources'; import {useToggleIndicateurConfidentiel} from './useToggleIndicateurConfidentiel'; import {useIndicateurInfoLiees} from './useIndicateurInfoLiees'; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts index 2cafead8e9..c85aa62f0a 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useImportSources.ts @@ -3,7 +3,8 @@ import {useQuery} from 'react-query'; import {supabaseClient} from 'core-logic/api/supabase'; import {useCollectiviteId} from 'core-logic/hooks/params'; import {naturalSort} from 'utils/naturalSort'; -import {SOURCE_COLLECTIVITE, SourceType} from '../types'; +import {SourceType} from '../types'; +import {SOURCE_COLLECTIVITE} from '../constants'; export type IndicateurImportSource = { id: string; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts index 3bdfd10a35..9959c5aae8 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts @@ -2,7 +2,8 @@ import {useQuery} from 'react-query'; import {DISABLE_AUTO_REFETCH, supabaseClient} from 'core-logic/api/supabase'; import {useCollectiviteId} from 'core-logic/hooks/params'; import {Enums} from '@tet/api'; -import {SOURCE_COLLECTIVITE, SourceType, TIndicateurDefinition} from './types'; +import {SourceType, TIndicateurDefinition} from './types'; +import {SOURCE_COLLECTIVITE} from './constants'; import {useIndicateurImportSources} from './detail/useImportSources'; export type TIndicateurValeur = { From 9d2bc627ea4aa240fdf48aab46e4ebed268628f4 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 7 May 2024 18:04:14 +0200 Subject: [PATCH 09/22] =?UTF-8?q?Raccorde=20la=20modale=20et=20la=20foncti?= =?UTF-8?q?on=20d'application=20des=20donn=C3=A9es=20externes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/ImportSourcesSelector.tsx | 110 +++++++++++++++--- .../Indicateurs/detail/IndicateurDetail.tsx | 1 + .../detail/IndicateurEnfantContent.tsx | 1 + .../detail/useEditIndicateurValeur.ts | 2 +- 4 files changed, 95 insertions(+), 19 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index 559a1a6064..5add942b87 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -1,31 +1,59 @@ -import {Alert, Button, Tab, Tabs} from '@tet/ui'; -import {SOURCE_COLLECTIVITE, SourceType} from '../types'; +import {useState} from 'react'; +import {Alert, Button, Modal, ModalFooterOKCancel, Tab, Tabs} from '@tet/ui'; +import {useCurrentCollectivite} from 'core-logic/hooks/useCurrentCollectivite'; +import {TIndicateurDefinition} from '../types'; +import {SOURCE_COLLECTIVITE} from '../constants'; import {IndicateurImportSource} from './useImportSources'; - -const SOURCE_TYPE_LABEL: Record = { - objectif: 'objectifs', - resultat: 'résultats', -}; - -const getSourceTypeLabel = (sourceType: SourceType | null) => - (sourceType && SOURCE_TYPE_LABEL[sourceType]) || null; +import {useApplyOpenData, useOpenDataComparaison} from './useApplyOpenData'; +import {ApplyOpenDataModal} from './ApplyOpenDataModal'; +import {getSourceTypeLabel} from '../constants'; /** * Affiche le sélecteur des sources de données d'un indicateur, lorsqu'il * y en a plusieurs. Sinon rien n'est affiché. */ export const ImportSourcesSelector = ({ + definition, sources, currentSource, setCurrentSource, }: { + definition: TIndicateurDefinition; sources?: IndicateurImportSource[] | null; currentSource: string; setCurrentSource?: (value: string) => void; }) => { const {indexedSources, idToIndex, indexToId, getSourceType} = useIndexedSources(sources); - const sourceTypeLabel = getSourceTypeLabel(getSourceType(currentSource)); + const s = sources?.find(s => s.id === currentSource); + const sourceType = getSourceType(currentSource); + const source = + (s && + sourceType && { + id: s.id, + type: sourceType, + nom: s.libelle, + }) || + undefined; + const sourceTypeLabel = getSourceTypeLabel(sourceType); + const comparaison = useOpenDataComparaison({ + definition, + importSource: currentSource, + }); + const canApplyOpenData = + currentSource !== SOURCE_COLLECTIVITE && + sourceTypeLabel && + !!(comparaison?.conflits || comparaison?.ajouts); + const collectivite = useCurrentCollectivite(); + const collectivite_id = collectivite?.collectivite_id || null; + + const {mutate: applyOpenData} = useApplyOpenData({ + collectivite_id, + definition, + source, + }); + const [isOpen, setIsOpen] = useState(false); + const [overwrite, setOverwrite] = useState(false); return indexedSources && setCurrentSource ? ( <> @@ -45,13 +73,59 @@ export const ImportSourcesSelector = ({ /> ))} - {currentSource !== SOURCE_COLLECTIVITE && sourceTypeLabel && ( - Appliquer à mes {sourceTypeLabel}} - /> + {canApplyOpenData && ( + <> + { + // ouvrir le dialogue de résolution des conflits si nécessaire + if (comparaison?.conflits) { + if (!source || !sourceType) return; + setIsOpen(true); + } else { + // applique les changements si nécessaire + applyOpenData({comparaison, overwrite: false}); + } + }} + > + Appliquer à mes {sourceTypeLabel} + + } + /> + {isOpen && source && sourceType && ( + ( + + )} + renderFooter={({close}) => ( + { + // applique les changements si nécessaire + applyOpenData({comparaison, overwrite}); + close(); + }, + }} + /> + )} + /> + )} + )} ) : null; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx index 527e40e8e4..a81d2df9d8 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx @@ -27,6 +27,7 @@ export const IndicateurDetail = ({ return ( <> { }; // recharge les valeurs et l'état "rempli" -const useOnSuccess = (args: TEditIndicateurValeurArgs) => { +export const useOnSuccess = (args: TEditIndicateurValeurArgs) => { const {collectivite_id, definition, type} = args; const {id: indicateur_id} = definition; const parent = (definition as TIndicateurPredefini).parent; From d1741acc88c2b10a05acf87db2baefec01b862a8 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 14 May 2024 11:54:41 +0200 Subject: [PATCH 10/22] =?UTF-8?q?Force=20l'affichage=20de=20l'onglet=20R?= =?UTF-8?q?=C3=A9sultats=20sil=20il=20n'y=20a=20pas=20d'onglet=20Objectifs?= =?UTF-8?q?=20quand=20on=20passe=20d'une=20source=20de=20donn=C3=A9es=20?= =?UTF-8?q?=C3=A0=20une=20autre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Indicateurs/detail/IndicateurValuesTabs.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx index 029388a8ee..eadf36b185 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTabs.tsx @@ -1,3 +1,4 @@ +import {useEffect} from 'react'; import {Tab, Tabs, useActiveTab} from 'ui/shared/Tabs'; import ToggleButton from 'ui/shared/designSystem/ToggleButton'; import DSTetTooltip from 'ui/shared/floating-ui/DSTetTooltip'; @@ -24,6 +25,15 @@ export const IndicateurValuesTabs = ({ const {data} = useIndicateurInfoLiees(definition); const {confidentiel} = data || {}; + // force l'affichage de l'onglet Résultats sil il n'y a pas d'onglet Objectifs + // quand on passe d'une source de données à une autre + const avecObjectifs = !importSource || importSource === SOURCE_COLLECTIVITE; + useEffect(() => { + if (activeTab === 1 && !avecObjectifs) { + onChangeTab(0); + } + }, [avecObjectifs, activeTab]); + return ( <> {!isReadonly && ( @@ -59,7 +69,7 @@ export const IndicateurValuesTabs = ({ /> )} - {!importSource || importSource === SOURCE_COLLECTIVITE ? ( + {avecObjectifs ? ( {activeTab === 1 && ( Date: Tue, 14 May 2024 17:09:22 +0200 Subject: [PATCH 11/22] =?UTF-8?q?Ajooute=20une=20option=20pour=20d=C3=A9sa?= =?UTF-8?q?ctiver=20le=20chargement=20auto=20des=20valeurs=20d'indicateur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collectivite/Indicateurs/useIndicateurValeurs.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts index 9959c5aae8..e897adb559 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts @@ -72,10 +72,13 @@ export const useIndicateurValeursEtCommentaires = ({ definition, type, importSource, + enabled = true, }: { definition: TIndicateurDefinition; - type: SourceType; + type: SourceType | null; importSource?: string; + /** Pour désactiver le chargement auto. */ + enabled?: boolean; }) => { const {id, isPerso} = definition; const collectivite_id = useCollectiviteId(); @@ -105,12 +108,13 @@ export const useIndicateurValeursEtCommentaires = ({ query.eq('type', 'import'); } else { query.is('source_id', null); - query.eq('type', 'resultat'); + query.neq('type', 'import'); } } const {data} = await query.returns(); return data; - } + }, + {enabled} ); }; From 1b4eae85dde0c441cc755fc0a2f456c5965337c0 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 14 May 2024 17:14:56 +0200 Subject: [PATCH 12/22] =?UTF-8?q?Enregistre=20le=20champ=20`source`=20quan?= =?UTF-8?q?d=20il=20est=20disponible=20en=20commentaire=20d'une=20valeur?= =?UTF-8?q?=20appliqu=C3=A9e=20depuis=20une=20source=20externe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/ImportSourcesSelector.tsx | 1 + .../Indicateurs/detail/useApplyOpenData.ts | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index 5add942b87..3a4e6ea8e1 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -39,6 +39,7 @@ export const ImportSourcesSelector = ({ const comparaison = useOpenDataComparaison({ definition, importSource: currentSource, + type: sourceType, }); const canApplyOpenData = currentSource !== SOURCE_COLLECTIVITE && diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts index 0981adc21a..7a7322c7e0 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts @@ -4,7 +4,10 @@ import {useMutation} from 'react-query'; import {supabaseClient} from 'core-logic/api/supabase'; -import {TIndicateurValeur, useIndicateurValeurs} from '../useIndicateurValeurs'; +import { + TIndicateurValeurEtCommentaires, + useIndicateurValeursEtCommentaires, +} from '../useIndicateurValeurs'; import {SourceType, TIndicateurDefinition} from '../types'; import {SOURCE_TYPE_LABEL} from '../constants'; import {useOnSuccess} from './useEditIndicateurValeur'; @@ -14,9 +17,9 @@ import {useOnSuccess} from './useEditIndicateurValeur'; */ export const compareOpenData = ( /** données actuelles */ - currentData: TIndicateurValeur[], + currentData: TIndicateurValeurEtCommentaires[], /** données à appliquer */ - openData: TIndicateurValeur[] + openData: TIndicateurValeurEtCommentaires[] ) => { if (!openData?.length) { // rien à appliquer @@ -29,7 +32,7 @@ export const compareOpenData = ( let ajouts = 0; // parcours chaque ligne à appliquer - const lignes = openData.map(({annee, valeur}) => { + const lignes = openData.map(({annee, valeur, source}) => { // cherche si une valeur a déjà été saisie pour la même année const existingData = currentData?.find(d => d.annee === annee); @@ -44,6 +47,7 @@ export const compareOpenData = ( annee, valeur: existingData?.valeur ?? null, nouvelleValeur: valeur, + source, }; } @@ -54,6 +58,7 @@ export const compareOpenData = ( annee, valeur: existingData.valeur, nouvelleValeur: valeur, + source, }; }); @@ -108,7 +113,24 @@ export const useApplyOpenData = ({ // enregistre les changements // TODO: à changer quand le modèle aura changé const table = `indicateur_${source.type}` as const; - return supabaseClient.from(table).upsert(toUpsert); + const {error} = await supabaseClient.from(table).upsert(toUpsert); + if (error) { + return false; + } + + // enregistre aussi le champ `source` en commentaire + const commentsToUpsert = filteredData! + .filter(({source}) => !!source) + .map(({annee, source}) => ({ + annee, + commentaire: source!, + collectivite_id, + indicateur_id: definition.id as string, + })); + const commentsTable = `indicateur_${source.type}_commentaire` as const; + return supabaseClient.from(commentsTable).upsert(commentsToUpsert, { + onConflict: 'collectivite_id,indicateur_id,annee', + }); }, { mutationKey: 'apply_open_data', @@ -134,13 +156,19 @@ export const useApplyOpenData = ({ export const useOpenDataComparaison = ({ definition, importSource, + type, }: { definition: TIndicateurDefinition; importSource: string; + type: SourceType | null; }) => { - const {data: currentData} = useIndicateurValeurs({id: definition.id}); - const {data: openData} = useIndicateurValeurs({ - id: definition.id, + const {data: currentData} = useIndicateurValeursEtCommentaires({ + definition, + type, + }); + const {data: openData} = useIndicateurValeursEtCommentaires({ + definition, + type, importSource, enabled: !!importSource, }); From ed22d527821f6417f9e72396de740b979e9095f5 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 14 May 2024 17:17:42 +0200 Subject: [PATCH 13/22] =?UTF-8?q?Change=20un=20libell=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collectivite/Indicateurs/detail/IndicateurValuesTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx index 96237553dd..2c359300c7 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurValuesTable.tsx @@ -88,7 +88,7 @@ const ValuesTableBase = ( {type === 'resultat' ? 'Résultat' : 'Objectif'} {unite && ({unite})} - Commentaires + Commentaires (Source, etc…) From b2fe613469afc97b36863d1b3cbdeee26e2e6283 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 14 May 2024 17:17:52 +0200 Subject: [PATCH 14/22] =?UTF-8?q?Met=20=C3=A0=20jour=20les=20storyshots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplyOpenDataModal.stories.storyshot | 182 +++++++++++++++++- 1 file changed, 178 insertions(+), 4 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot index ea7a54b63a..0455bd9f60 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot @@ -21,7 +21,8 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal
- Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. + Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. + Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes.
@@ -189,7 +190,8 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal
- Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. + Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. + Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes.
@@ -358,7 +360,8 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal
- Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. + Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. + Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes.
@@ -505,6 +508,176 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal `; +exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal En Conflit Partiel Ecrasement 1`] = ` +
+
+ +
+
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. + Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
+
+
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ Date + + + + Mes + objectifs + + ( + teqCO2 + ) + + + + objectifs + + + PCAET + + ( + teqCO2 + ) + +
+ 2022 + + 141 299 + + 150 000 +
+ 2021 + + 141 299 + + 141 299 +
+ + + + + + + + + + + + + + +
+ Après validation + + + + objectifs + + PCAET + + + ( + teqCO2 + ) + +
+ 150 000 +
+ 141 299 +
+
+
+`; + exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal Sans Conflits 1`] = `
- Vous êtes sur le point d’appliquer les « résultats PCAET » à vos résultats. Attention : certaines données des « résultats PCAET » entrent en conflit avec vos résultats et ont des valeurs différentes. + Vous êtes sur le point d’appliquer les « résultats PCAET » à vos résultats. + Attention : certaines données des « résultats PCAET » entrent en conflit avec vos résultats et ont des valeurs différentes.
From ba12ac052c759bdef3842149162978762618d77a Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Thu, 16 May 2024 16:07:34 +0200 Subject: [PATCH 15/22] Ajoute des commentaires --- .../detail/ImportSourcesSelector.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index 3a4e6ea8e1..5a90b5b0c4 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -23,8 +23,11 @@ export const ImportSourcesSelector = ({ currentSource: string; setCurrentSource?: (value: string) => void; }) => { + // utilitaire pour faire correspondre les index d'onglet aux id de source const {indexedSources, idToIndex, indexToId, getSourceType} = useIndexedSources(sources); + + // source sélectionnée const s = sources?.find(s => s.id === currentSource); const sourceType = getSourceType(currentSource); const source = @@ -35,28 +38,40 @@ export const ImportSourcesSelector = ({ nom: s.libelle, }) || undefined; + + // libellé en fonction du type de source const sourceTypeLabel = getSourceTypeLabel(sourceType); + + // compare les données open-data avec les données courantes (si la source est externe) const comparaison = useOpenDataComparaison({ definition, importSource: currentSource, type: sourceType, }); + + // détermine si le bouton "appliquer à mes objectifs/résultats" doit être affiché const canApplyOpenData = currentSource !== SOURCE_COLLECTIVITE && sourceTypeLabel && !!(comparaison?.conflits || comparaison?.ajouts); + + // collectivité courante const collectivite = useCurrentCollectivite(); const collectivite_id = collectivite?.collectivite_id || null; + // mutation pour appliquer les données const {mutate: applyOpenData} = useApplyOpenData({ collectivite_id, definition, source, }); + + // état local de la modale de résolution des conflits const [isOpen, setIsOpen] = useState(false); const [overwrite, setOverwrite] = useState(false); return indexedSources && setCurrentSource ? ( + /** onglets de sélection de la source si il y a des sources open-data dispo */ <> {canApplyOpenData && ( + /** bandeau & bouton "appliquer à mes objectifs/résultats" */ <> {isOpen && source && sourceType && ( + /** modale de résolution des conflits */ Date: Thu, 16 May 2024 16:10:00 +0200 Subject: [PATCH 16/22] =?UTF-8?q?Ajoute=20les=20d=C3=A9finitions=20pour=20?= =?UTF-8?q?le=20tracking=20de=20l'application=20des=20sources=20open=20dat?= =?UTF-8?q?a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/tracking/trackingPlan.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/ui/src/components/tracking/trackingPlan.ts b/packages/ui/src/components/tracking/trackingPlan.ts index 4eaeb8de2c..41803bdd3f 100644 --- a/packages/ui/src/components/tracking/trackingPlan.ts +++ b/packages/ui/src/components/tracking/trackingPlan.ts @@ -50,10 +50,16 @@ type AuthPageAvecOnglets = { events: {cta_submit: {}}; }; +type OpenDataSource = { + source_id: string; + type: 'resultat' | 'objectif'; +}; + /** * Permet de respecter le plan de tracking. */ export interface TrackingPlan extends Record { + /** Page indicateur perso */ 'app/indicateurs/perso': { properties: {collectivite_id: number}; onglets: never; @@ -62,6 +68,25 @@ export interface TrackingPlan extends Record { }; }; + /** Page indicateur prédéfini */ + 'app/indicateurs/predefini': { + properties: {collectivite_id: number; indicateur_id: string}; + onglets: never; + events: { + /** Consultation des données open data par fournisseur */ + view_open_data: OpenDataSource; + /** Applique une source open data aux résultats ou objectifs */ + apply_open_data: OpenDataSource & {overwrite: boolean}; + }; + }; + + /** Modale qui affiche les données open-data en conflits avec les données déjà saisies */ + 'app/indicateurs/predefini/conflits': { + properties: {collectivite_id: number; indicateur_id: string}; + onglets: never; + events: never; + }; + /* La page à la racine de https://auth.territoiresentransitions.fr */ 'auth/': NoProps; From 166697a19be7c3687176b8af38daf9d81ef9db1a Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Thu, 16 May 2024 16:51:05 +0200 Subject: [PATCH 17/22] Ajoute le tracking de l'application des sources open data --- .../Indicateurs/IndicateurPredefini.tsx | 8 ++++ .../detail/ImportSourcesSelector.tsx | 48 +++++++++++++++---- .../Indicateurs/detail/useApplyOpenData.ts | 25 ++++++++-- 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/IndicateurPredefini.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/IndicateurPredefini.tsx index b08df41dbe..19a252a1a0 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/IndicateurPredefini.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/IndicateurPredefini.tsx @@ -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 = ({ @@ -18,8 +20,14 @@ export const IndicateurPredefiniBase = ({ definition, ]); + const collectivite_id = useCollectiviteId()!; + return ( <> +
diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index 5a90b5b0c4..0ef8ef1c38 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -1,5 +1,14 @@ import {useState} from 'react'; -import {Alert, Button, Modal, ModalFooterOKCancel, Tab, Tabs} from '@tet/ui'; +import { + Alert, + Button, + Modal, + ModalFooterOKCancel, + Tab, + Tabs, + TrackPageView, + useEventTracker, +} from '@tet/ui'; import {useCurrentCollectivite} from 'core-logic/hooks/useCurrentCollectivite'; import {TIndicateurDefinition} from '../types'; import {SOURCE_COLLECTIVITE} from '../constants'; @@ -70,13 +79,25 @@ export const ImportSourcesSelector = ({ const [isOpen, setIsOpen] = useState(false); const [overwrite, setOverwrite] = useState(false); + const trackEvent = useEventTracker('app/indicateurs/predefini'); + return indexedSources && setCurrentSource ? ( /** onglets de sélection de la source si il y a des sources open-data dispo */ <> setCurrentSource(indexToId(activeTab))} + onChange={activeTab => { + const sourceId = indexToId(activeTab); + setCurrentSource(sourceId); + if (sourceId !== SOURCE_COLLECTIVITE) + trackEvent('view_open_data', { + collectivite_id: collectivite_id!, + indicateur_id: definition.id as string, + source_id: sourceId, + type: sourceType || 'resultat', + }); + }} > {indexedSources?.map(({id, libelle}) => ( ( - + <> + + + )} renderFooter={({close}) => ( { + const trackEvent = useEventTracker('app/indicateurs/predefini'); + + const type = source?.type || 'resultat'; + const onSuccess = useOnSuccess({ + collectivite_id, + definition, + type, + }); + return useMutation( async ({ comparaison, @@ -141,11 +151,16 @@ export const useApplyOpenData = ({ source.nom } ont bien été appliqués`, }, - onSuccess: useOnSuccess({ - collectivite_id, - definition, - type: source?.type || 'resultat', - }), + onSuccess: (data, {overwrite}) => { + onSuccess(); + trackEvent('apply_open_data', { + collectivite_id: collectivite_id!, + indicateur_id: definition.id as string, + source_id: source!.id, + type, + overwrite, + }); + }, } ); }; From 3aad4d126c1732574d3e4cf2ef7907e6d5cd1233 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Thu, 16 May 2024 17:50:44 +0200 Subject: [PATCH 18/22] =?UTF-8?q?Met=20=C3=A0=20jour=20les=20storyshots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplyOpenDataModal.stories.storyshot | 140 ++++++++++-------- 1 file changed, 80 insertions(+), 60 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot index 0455bd9f60..3a349ec707 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/__snapshots__/ApplyOpenDataModal.stories.storyshot @@ -5,24 +5,28 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal className="flex flex-col gap-8" >
-
+
- Conflit détecté -
-
- Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. +
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
@@ -174,24 +178,28 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal className="flex flex-col gap-8" >
-
+
- Conflit détecté -
-
- Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. +
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
@@ -344,24 +352,28 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal className="flex flex-col gap-8" >
-
+
- Conflit détecté -
-
- Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. +
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
@@ -513,24 +525,28 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal className="flex flex-col gap-8" >
-
+
- Conflit détecté -
-
- Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. +
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « objectifs PCAET » à vos objectifs. Attention : certaines données des « objectifs PCAET » entrent en conflit avec vos objectifs et ont des valeurs différentes. +
@@ -808,24 +824,28 @@ exports[`Storyshots app/pages/collectivite/Indicateurs/detail/ApplyOpenDataModal className="flex flex-col gap-8" >
-
+
- Conflit détecté -
-
- Vous êtes sur le point d’appliquer les « résultats PCAET » à vos résultats. +
+ Conflit détecté +
+
+ Vous êtes sur le point d’appliquer les « résultats PCAET » à vos résultats. Attention : certaines données des « résultats PCAET » entrent en conflit avec vos résultats et ont des valeurs différentes. +
From 6d805249601da2beb41cc7dd24dfcb27036147a1 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Thu, 16 May 2024 17:59:38 +0200 Subject: [PATCH 19/22] Fixe un test --- api_tests/tests/indicateurs/filtre.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_tests/tests/indicateurs/filtre.test.ts b/api_tests/tests/indicateurs/filtre.test.ts index 37d62dfd7c..814c1befda 100644 --- a/api_tests/tests/indicateurs/filtre.test.ts +++ b/api_tests/tests/indicateurs/filtre.test.ts @@ -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, From 10c143979ea27f10866556bc3034c389e543e782 Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 21 May 2024 14:54:26 +0200 Subject: [PATCH 20/22] =?UTF-8?q?Change=20un=20typage=20et=20d=C3=A9place?= =?UTF-8?q?=20une=20condition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Indicateurs/detail/ImportSourcesSelector.tsx | 8 ++++---- .../Indicateurs/detail/IndicateurDetail.tsx | 15 ++++++++------- .../detail/IndicateurEnfantContent.tsx | 14 ++++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx index 0ef8ef1c38..f913570a46 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ImportSourcesSelector.tsx @@ -28,16 +28,16 @@ export const ImportSourcesSelector = ({ setCurrentSource, }: { definition: TIndicateurDefinition; - sources?: IndicateurImportSource[] | null; + sources: IndicateurImportSource[]; currentSource: string; - setCurrentSource?: (value: string) => void; + setCurrentSource: (value: string) => void; }) => { // utilitaire pour faire correspondre les index d'onglet aux id de source const {indexedSources, idToIndex, indexToId, getSourceType} = useIndexedSources(sources); // source sélectionnée - const s = sources?.find(s => s.id === currentSource); + const s = sources.find(s => s.id === currentSource); const sourceType = getSourceType(currentSource); const source = (s && @@ -179,7 +179,7 @@ export const ImportSourcesSelector = ({ ) : null; }; -/** +/* * Ajoute la source "mes données" à l'index 0 et renvoi des fonctions * utilitaires pour transformer les id en index et réciproquement. */ diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx index a81d2df9d8..9e3ba081c2 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx @@ -26,13 +26,14 @@ export const IndicateurDetail = ({ return ( <> - - + {!!sources?.length && ( + + )} - + {!!sources?.length && ( + + )} Date: Tue, 21 May 2024 14:56:48 +0200 Subject: [PATCH 21/22] =?UTF-8?q?Enl=C3=A8ve=20une=20condition=20inutile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/collectivite/Indicateurs/detail/useApplyOpenData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts index 2d376e9f75..86086cb909 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/useApplyOpenData.ts @@ -22,7 +22,7 @@ export const compareOpenData = ( /** données à appliquer */ openData: TIndicateurValeurEtCommentaires[] ) => { - if (!openData?.length) { + if (!openData.length) { // rien à appliquer return null; } From 1a807845bc35779892607605d57e7b15f8f3c88e Mon Sep 17 00:00:00 2001 From: Marc Rutkowski Date: Tue, 21 May 2024 15:14:52 +0200 Subject: [PATCH 22/22] =?UTF-8?q?Simplifie=20et=20r=C3=A9pare=20une=20cond?= =?UTF-8?q?ition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Indicateurs/useIndicateurValeurs.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts index e897adb559..22a81e54b5 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/useIndicateurValeurs.ts @@ -99,17 +99,12 @@ export const useIndicateurValeursEtCommentaires = ({ .not('valeur', 'is', null) .order('annee', {ascending: false}); - if (type === 'objectif') { - query.is('source_id', null); - query.eq('type', type); + if (importSource && importSource !== SOURCE_COLLECTIVITE) { + query.eq('source_id', importSource); + query.eq('type', 'import'); } else { - if (importSource && importSource !== SOURCE_COLLECTIVITE) { - query.eq('source_id', importSource); - query.eq('type', 'import'); - } else { - query.is('source_id', null); - query.neq('type', 'import'); - } + query.is('source_id', null); + query.eq('type', type === 'objectif' ? type : 'resultat'); } const {data} = await query.returns();