From 8be255e15a42f52b405f7899a454e791215e358f Mon Sep 17 00:00:00 2001 From: Marine Heckler Date: Wed, 8 Jan 2025 17:40:53 +0100 Subject: [PATCH 1/5] =?UTF-8?q?Cr=C3=A9ation=20d'un=20nouveau=20layout=20p?= =?UTF-8?q?our=20la=20page=20indicateur,=20et=20mise=20=C3=A0=20jour=20sur?= =?UTF-8?q?=20les=20indicateurs=20personnalis=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CollectivitePageLayout.tsx | 8 +- .../Indicateur/FichesActionLiees.tsx | 4 +- .../Indicateurs/Indicateur/Indicateur.tsx | 5 +- .../Indicateur/detail/HeaderIndicateur.tsx | 17 ++- .../Indicateur/detail/IndicateurInfoLiees.tsx | 4 +- .../detail/IndicateurValuesTabs.tsx | 57 ++++---- .../components/BadgeIndicateurPerso.tsx | 2 +- .../detail/DescriptionIndicateurInput.tsx | 26 ++++ .../Indicateurs/detail/DonneesIndicateur.tsx | 61 ++++++++ .../Indicateurs/detail/IndicateurDetail.tsx | 17 +++ .../Indicateurs/detail/IndicateurLayout.tsx | 131 ++++++++++++++++++ .../Indicateurs/detail/IndicateurToolbar.tsx | 86 ++++++++++++ .../detail/UniteIndicateurInput.tsx | 26 ++++ 13 files changed, 399 insertions(+), 45 deletions(-) create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DescriptionIndicateurInput.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/UniteIndicateurInput.tsx diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/CollectivitePageLayout/CollectivitePageLayout.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/CollectivitePageLayout/CollectivitePageLayout.tsx index f430323f25..5564529fa8 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/CollectivitePageLayout/CollectivitePageLayout.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/CollectivitePageLayout/CollectivitePageLayout.tsx @@ -1,12 +1,12 @@ +import classNames from 'classnames'; import React, { useEffect, useMemo, useState } from 'react'; -import SideNavContainer, { SideNavContainerProps } from './SideNavContainer'; +import Panel from './Panel/Panel'; import { PanelProvider, usePanelDispatch, usePanelState, } from './Panel/PanelContext'; -import classNames from 'classnames'; -import Panel from './Panel/Panel'; +import SideNavContainer, { SideNavContainerProps } from './SideNavContainer'; type Props = { children: React.ReactNode; @@ -62,7 +62,7 @@ const PageLayout = ({ children, sideNav, dataTest }: Props) => { return (
{/** Side nav */} {sideNav && ( diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/FichesActionLiees.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/FichesActionLiees.tsx index afb5db1cad..ef74499c59 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/FichesActionLiees.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/FichesActionLiees.tsx @@ -26,7 +26,7 @@ export const FichesActionLiees = (props: TFichesActionProps) => { const isReadonly = collectivite?.readonly ?? false; return ( - <> +
{ - +
); }; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx index 408731d8ea..ebb575efa9 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx @@ -8,7 +8,7 @@ import { import { useCollectiviteId } from '@/app/core-logic/hooks/params'; import { redirect } from 'next/navigation'; import { useParams } from 'react-router-dom'; -import { IndicateurPersonnalise } from './IndicateurPersonnalise'; +import IndicateurDetail from '../detail/IndicateurDetail'; import { IndicateurPredefini } from './IndicateurPredefini'; /** @@ -49,7 +49,8 @@ const Indicateur = () => { } > {isPerso ? ( - + // + ) : ( )} diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/HeaderIndicateur.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/HeaderIndicateur.tsx index 7ff3113de8..0859e2068e 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/HeaderIndicateur.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/HeaderIndicateur.tsx @@ -52,7 +52,7 @@ export const HeaderIndicateur = ({ return (
- + {!isReadonly && ( + + )}
); diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurInfoLiees.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurInfoLiees.tsx index 4588a239d3..b1dc3b79ef 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurInfoLiees.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurInfoLiees.tsx @@ -56,7 +56,7 @@ export const IndicateurInfoLiees = (props: TIndicateurInfoLieesProps) => { .filter((id) => !!id) as string[]; return ( - <> +
{/** personne pilote */} { /> )} - +
); }; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurValuesTabs.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurValuesTabs.tsx index 0c14b787d7..c7c4d84766 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurValuesTabs.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurValuesTabs.tsx @@ -57,7 +57,34 @@ export const IndicateurValuesTabs = ({ }, [avecObjectifs, avecResultats, activeTab]); return ( - <> +
+ + {avecResultats ? ( + + + + ) : null} + {avecObjectifs ? ( + + + + ) : null} + + {!isReadonly && ( <>
@@ -92,32 +119,6 @@ export const IndicateurValuesTabs = ({ )} )} - - {avecResultats ? ( - - - - ) : null} - {avecObjectifs ? ( - - - - ) : null} - - +
); }; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/components/BadgeIndicateurPerso.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/components/BadgeIndicateurPerso.tsx index 848302d804..4e357876a8 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/components/BadgeIndicateurPerso.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/components/BadgeIndicateurPerso.tsx @@ -10,7 +10,7 @@ const BadgeIndicateurPerso = ({ size }: Props) => { size={size} light iconPosition="left" - icon="line-chart-line" + icon="user-line" /> ); }; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DescriptionIndicateurInput.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DescriptionIndicateurInput.tsx new file mode 100644 index 0000000000..00a33f6a91 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DescriptionIndicateurInput.tsx @@ -0,0 +1,26 @@ +import { AutoResizedTextarea, Field } from '@/ui'; + +type Props = { + description: string | undefined | null; + disabled?: boolean; + updateDescription: (value: string) => void; +}; + +const DescriptionIndicateurInput = ({ + description, + disabled, + updateDescription, +}: Props) => { + return ( + + updateDescription(evt.currentTarget.value)} + /> + + ); +}; + +export default DescriptionIndicateurInput; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx new file mode 100644 index 0000000000..af5b67de39 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx @@ -0,0 +1,61 @@ +import IndicateurDetailChart from '../Indicateur/detail/IndicateurDetailChart'; +import { IndicateurInfoLiees } from '../Indicateur/detail/IndicateurInfoLiees'; +import { IndicateurValuesTabs } from '../Indicateur/detail/IndicateurValuesTabs'; +import { TIndicateurDefinition } from '../types'; +import DescriptionIndicateurInput from './DescriptionIndicateurInput'; +import UniteIndicateurInput from './UniteIndicateurInput'; + +type Props = { + definition: TIndicateurDefinition; + isPerso?: boolean; + isReadonly?: boolean; + updateUnite: (value: string) => void; + updateDescription: (value: string) => void; +}; + +const DonneesIndicateur = ({ + definition, + isPerso = false, + isReadonly = false, + updateUnite, + updateDescription, +}: Props) => { + const { description, unite, rempli, titre } = definition; + + return ( +
+ {/* Graphe */} + + + {/* Tableau */} + + + {/* Description */} + + + {/* Infos liées - à déplacer */} + + + {/* Unité personnalisée - à déplacer */} + {isPerso && ( + + )} +
+ ); +}; + +export default DonneesIndicateur; 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 new file mode 100644 index 0000000000..ee841e4855 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurDetail.tsx @@ -0,0 +1,17 @@ +import { useIndicateurDefinition } from '../Indicateur/useIndicateurDefinition'; +import IndicateurLayout from './IndicateurLayout'; + +type Props = { + indicateurId: number | string; + isPerso?: boolean; +}; + +const IndicateurDetail = ({ indicateurId, isPerso = false }: Props) => { + const definition = useIndicateurDefinition(indicateurId); + + if (!definition) return null; + + return ; +}; + +export default IndicateurDetail; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx new file mode 100644 index 0000000000..564f1a67b7 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx @@ -0,0 +1,131 @@ +import { referentielToName } from '@/app/app/labels'; +import BadgeIndicateurPerso from '@/app/app/pages/collectivite/Indicateurs/components/BadgeIndicateurPerso'; +import { useCurrentCollectivite } from '@/app/core-logic/hooks/useCurrentCollectivite'; +import ScrollTopButton from '@/app/ui/buttons/ScrollTopButton'; +import { BadgeACompleter } from '@/app/ui/shared/Badge/BadgeACompleter'; +import { Badge, Tab, Tabs } from '@/ui'; +import ActionsLieesListe from '../../PlansActions/FicheAction/ActionsLiees/ActionsLieesListe'; +import { FichesActionLiees } from '../Indicateur/FichesActionLiees'; +import { HeaderIndicateur } from '../Indicateur/detail/HeaderIndicateur'; +import { useUpdateIndicateurDefinition } from '../Indicateur/useUpdateIndicateurDefinition'; +import BadgeOpenData from '../components/BadgeOpenData'; +import { TIndicateurDefinition } from '../types'; +import DonneesIndicateur from './DonneesIndicateur'; +import IndicateurToolbar from './IndicateurToolbar'; + +type IndicateurLayoutProps = { + dataTest?: string; + definition: TIndicateurDefinition; + isPerso?: boolean; +}; + +const IndicateurLayout = ({ + dataTest, + definition, + isPerso = false, +}: IndicateurLayoutProps) => { + const { titre, rempli } = definition; + + const { mutate: updateDefinition } = useUpdateIndicateurDefinition(); + const collectivite = useCurrentCollectivite(); + + const collectiviteId = collectivite?.collectivite_id; + const isReadonly = !collectivite || collectivite?.readonly; + + // Mise à jour des champs de l'indicateur + const handleUpdate = ( + name: 'description' | 'commentaire' | 'unite' | 'titre', + value: string + ) => { + const trimmedValue = value.trim(); + if (collectiviteId && trimmedValue !== definition[name]) { + updateDefinition({ ...definition, [name]: trimmedValue }); + } + }; + + const handleTitreUpdate = (value: string) => handleUpdate('titre', value); + + const handleUniteUpdate = (value: string) => handleUpdate('unite', value); + + /** + * TEMPORARY: currently, description input feeds two columns: + * `description` column in `indicateur_definition` + * `commentaire` column in `indicateur_collectivite` (via the hardcoded ['commentaire'] prop). + * + * TO DO: remove this function and change + * handleUpdate('description', e.target.value) to handleUpdate('commentaire', e.target.value). + * + * Related to this PR: https://github.com/incubateur-ademe/territoires-en-transitions/pull/3313. + */ + const handleDescriptionUpdate = (value: string) => { + const trimmedValue = value.trim(); + updateDefinition({ + ...definition, + description: trimmedValue, + commentaire: trimmedValue, + }); + }; + + return ( +
+ + +
+
+
+ + + {definition.participationScore && ( + + )} + {definition.hasOpenData && } +
+ + +
+ + {/* Indicateur sans enfant, groupe d'indicateurs avec agrégation, + ou indicateur personnalisé */} + + {/* Données */} + + + + + {/* Actions des référentiels liées */} + {!isPerso ? ( + + a.id)} + /> + + ) : undefined} + + {/* Fiches des plans liées */} + + + + + + +
+
+ ); +}; + +export default IndicateurLayout; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx new file mode 100644 index 0000000000..8bcbb82720 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx @@ -0,0 +1,86 @@ +import { ToolbarIconButton } from '@/app/ui/buttons/ToolbarIconButton'; +import { Modal, ModalFooterOKCancel } from '@/ui'; +import { useState } from 'react'; +import { IndicateurSidePanelToolbar } from '../Indicateur/IndicateurSidePanelToolbar'; +import { useExportIndicateurs } from '../Indicateur/useExportIndicateurs'; +import { useDeleteIndicateurPerso } from '../Indicateur/useRemoveIndicateurPerso'; +import { TIndicateurDefinition } from '../types'; + +type Props = { + definition: TIndicateurDefinition; + collectiviteId: number; + isPerso?: boolean; + isReadonly?: boolean; +}; + +const IndicateurToolbar = ({ + definition, + collectiviteId, + isPerso = false, + isReadonly = false, +}: Props) => { + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + + const { mutate: exportIndicateurs, isLoading } = useExportIndicateurs( + isPerso ? 'app/indicateurs/perso' : 'app/indicateurs/predefini', + [definition] + ); + + const { mutate: deleteIndicateurPerso } = useDeleteIndicateurPerso( + collectiviteId, + definition.id + ); + + return ( + <> +
+ exportIndicateurs()} + /> + {!isReadonly && isPerso && ( + setIsDeleteModalOpen(true)} + /> + )} + {!isPerso && } +
+ + {isDeleteModalOpen && ( + ( + close(), + }} + btnOKProps={{ + 'aria-label': 'Supprimer', + children: 'Supprimer', + onClick: () => { + deleteIndicateurPerso(); + close(); + }, + }} + /> + )} + /> + )} + + ); +}; + +export default IndicateurToolbar; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/UniteIndicateurInput.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/UniteIndicateurInput.tsx new file mode 100644 index 0000000000..77298e33fe --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/UniteIndicateurInput.tsx @@ -0,0 +1,26 @@ +import { Field, Input } from '@/ui'; +import { useState } from 'react'; + +type Props = { + unite: string; + disabled?: boolean; + updateUnite: (value: string) => void; +}; + +const UniteIndicateurInput = ({ unite, disabled, updateUnite }: Props) => { + const [uniteInput, setUniteInput] = useState(unite); + + return ( + + setUniteInput(evt.target.value)} + onBlur={(evt) => updateUnite(evt.target.value)} + disabled={disabled} + /> + + ); +}; + +export default UniteIndicateurInput; From ada346eaf175c1eb695816422a29e10994f72cb6 Mon Sep 17 00:00:00 2001 From: Marine Heckler Date: Thu, 9 Jan 2025 11:50:25 +0100 Subject: [PATCH 2/5] =?UTF-8?q?Applique=20le=20nouveau=20layout=20=C3=A0?= =?UTF-8?q?=20la=20page=20indicateur=20pr=C3=A9d=C3=A9fini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Indicateurs/Indicateur/Indicateur.tsx | 16 +-- .../Indicateur/detail/IndicateurCompose.tsx | 4 +- .../Indicateurs/detail/DonneesIndicateur.tsx | 27 ++++- .../Indicateurs/detail/IndicateurDetail.tsx | 9 +- .../Indicateurs/detail/IndicateurLayout.tsx | 103 +++++++++++------- .../Indicateurs/detail/IndicateurToolbar.tsx | 5 +- .../Indicateurs/detail/SousIndicateurs.tsx | 41 +++++++ 7 files changed, 148 insertions(+), 57 deletions(-) create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/SousIndicateurs.tsx diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx index ebb575efa9..8503fc29c8 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/Indicateur.tsx @@ -9,7 +9,6 @@ import { useCollectiviteId } from '@/app/core-logic/hooks/params'; import { redirect } from 'next/navigation'; import { useParams } from 'react-router-dom'; import IndicateurDetail from '../detail/IndicateurDetail'; -import { IndicateurPredefini } from './IndicateurPredefini'; /** * Affiche le détail d'un indicateur @@ -42,19 +41,12 @@ const Indicateur = () => { } return ( -
- {isPerso ? ( - // - - ) : ( - - )} -
+ {...{ indicateurId, isPerso }} + /> ); }; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurCompose.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurCompose.tsx index d4788eaaf2..db3ec141eb 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurCompose.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/Indicateur/detail/IndicateurCompose.tsx @@ -59,7 +59,9 @@ export const IndicateurCompose = ({ ); }; // détermine les actions liées communes à un ensemble de définitions -const findCommonLinkedActions = (definitions: IndicateurDefinition[]) => { +export const findCommonLinkedActions = ( + definitions: IndicateurDefinition[] +) => { // extrait les tableaux d'ids const actionsIds = definitions.map(({ actions }) => actions.map((a) => a.id)); diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx index af5b67de39..504eb04346 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/DonneesIndicateur.tsx @@ -1,6 +1,8 @@ +import { ImportSourcesSelector } from '../Indicateur/detail/ImportSourcesSelector'; import IndicateurDetailChart from '../Indicateur/detail/IndicateurDetailChart'; import { IndicateurInfoLiees } from '../Indicateur/detail/IndicateurInfoLiees'; import { IndicateurValuesTabs } from '../Indicateur/detail/IndicateurValuesTabs'; +import { useIndicateurImportSources } from '../Indicateur/detail/useImportSources'; import { TIndicateurDefinition } from '../types'; import DescriptionIndicateurInput from './DescriptionIndicateurInput'; import UniteIndicateurInput from './UniteIndicateurInput'; @@ -20,25 +22,42 @@ const DonneesIndicateur = ({ updateUnite, updateDescription, }: Props) => { - const { description, unite, rempli, titre } = definition; + const { description, commentaire, unite, rempli, titre, titreLong } = + definition; + + const { sources, currentSource, setCurrentSource } = + useIndicateurImportSources(definition.id); return (
+ {!!sources?.length && ( + + )} + {/* Graphe */} {/* Tableau */} - + {/* Description */} 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 ee841e4855..bb77cf935a 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 @@ -2,16 +2,21 @@ import { useIndicateurDefinition } from '../Indicateur/useIndicateurDefinition'; import IndicateurLayout from './IndicateurLayout'; type Props = { + dataTest?: string; indicateurId: number | string; isPerso?: boolean; }; -const IndicateurDetail = ({ indicateurId, isPerso = false }: Props) => { +const IndicateurDetail = ({ + dataTest, + indicateurId, + isPerso = false, +}: Props) => { const definition = useIndicateurDefinition(indicateurId); if (!definition) return null; - return ; + return ; }; export default IndicateurDetail; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx index 564f1a67b7..a769a2e8b3 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx @@ -12,6 +12,7 @@ import BadgeOpenData from '../components/BadgeOpenData'; import { TIndicateurDefinition } from '../types'; import DonneesIndicateur from './DonneesIndicateur'; import IndicateurToolbar from './IndicateurToolbar'; +import SousIndicateurs from './SousIndicateurs'; type IndicateurLayoutProps = { dataTest?: string; @@ -24,14 +25,18 @@ const IndicateurLayout = ({ definition, isPerso = false, }: IndicateurLayoutProps) => { - const { titre, rempli } = definition; + const { enfants, sansValeur, rempli, titre } = definition; const { mutate: updateDefinition } = useUpdateIndicateurDefinition(); + const collectivite = useCurrentCollectivite(); const collectiviteId = collectivite?.collectivite_id; const isReadonly = !collectivite || collectivite?.readonly; + const composeSansAgregation = !!enfants && enfants.length > 0 && sansValeur; + const composeAvecAgregation = !!enfants && enfants.length > 0 && !sansValeur; + // Mise à jour des champs de l'indicateur const handleUpdate = ( name: 'description' | 'commentaire' | 'unite' | 'titre', @@ -45,6 +50,9 @@ const IndicateurLayout = ({ const handleTitreUpdate = (value: string) => handleUpdate('titre', value); + const handleCommentaireUpdate = (value: string) => + handleUpdate('commentaire', value); + const handleUniteUpdate = (value: string) => handleUpdate('unite', value); /** @@ -76,51 +84,72 @@ const IndicateurLayout = ({
-
- - - {definition.participationScore && ( - - )} - {definition.hasOpenData && } -
- + {/* Liste des badges */} + {!composeSansAgregation && ( +
+ + {isPerso && } + {definition.participationScore && ( + + )} + {definition.hasOpenData && } +
+ )} + + {/* Menu export / infos / suppression */}
- {/* Indicateur sans enfant, groupe d'indicateurs avec agrégation, - ou indicateur personnalisé */} - - {/* Données */} - - - - - {/* Actions des référentiels liées */} - {!isPerso ? ( - - a.id)} + {composeSansAgregation ? ( + // Groupe d'indicateurs sans agrégation + + ) : ( + // Indicateur sans enfant, groupe d'indicateurs avec agrégation, + // ou indicateur personnalisé + + {/* Données */} + + + isPerso + ? handleDescriptionUpdate(value) + : handleCommentaireUpdate(value) + } /> - ) : undefined} - {/* Fiches des plans liées */} - - - - + {/* Sous indicateurs */} + {composeAvecAgregation ? ( + + + + ) : undefined} + + {/* Actions des référentiels liées */} + {!isPerso ? ( + + a.id)} + /> + + ) : undefined} + + {/* Fiches des plans liées */} + + + + + )}
diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx index 8bcbb82720..fe7976d2bb 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurToolbar.tsx @@ -1,5 +1,6 @@ import { ToolbarIconButton } from '@/app/ui/buttons/ToolbarIconButton'; import { Modal, ModalFooterOKCancel } from '@/ui'; +import classNames from 'classnames'; import { useState } from 'react'; import { IndicateurSidePanelToolbar } from '../Indicateur/IndicateurSidePanelToolbar'; import { useExportIndicateurs } from '../Indicateur/useExportIndicateurs'; @@ -11,6 +12,7 @@ type Props = { collectiviteId: number; isPerso?: boolean; isReadonly?: boolean; + className?: string; }; const IndicateurToolbar = ({ @@ -18,6 +20,7 @@ const IndicateurToolbar = ({ collectiviteId, isPerso = false, isReadonly = false, + className, }: Props) => { const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); @@ -33,7 +36,7 @@ const IndicateurToolbar = ({ return ( <> -
+
{ + const { data: enfants } = useIndicateurDefinitions(definition.id, enfantsIds); + + if (!enfants?.length) return null; + + const actionsLieesCommunes = findCommonLinkedActions([ + definition, + ...enfants, + ]); + + const enfantsTries = enfants.sort((a, b) => { + if (!a.identifiant || !b.identifiant) { + return 0; + } + return a.identifiant.localeCompare(b.identifiant); + }); + + return ( +
+ {enfantsTries.map((enfant) => ( + + ))} +
+ ); +}; + +export default SousIndicateurs; From 179372c99b9133593594d53dcd32ac041a9a58d8 Mon Sep 17 00:00:00 2001 From: Marine Heckler Date: Fri, 10 Jan 2025 14:36:25 +0100 Subject: [PATCH 3/5] =?UTF-8?q?Onglet=20fiches=20actions=20li=C3=A9es=20su?= =?UTF-8?q?r=20la=20page=20indicateur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Indicateurs/detail/FichesLiees.tsx | 85 ++++++++++++ .../Indicateurs/detail/IndicateurLayout.tsx | 9 +- .../FicheAction/Carte/FicheActionCard.tsx | 30 +++-- .../Carte/FicheActionFooterInfo.tsx | 123 +++++++++++------- .../FichesLiees/ModaleFichesLiees.tsx | 2 +- .../FichesActionListe.tsx | 29 +++-- 6 files changed, 206 insertions(+), 72 deletions(-) create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/FichesLiees.tsx diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/FichesLiees.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/FichesLiees.tsx new file mode 100644 index 0000000000..d566b5e836 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/FichesLiees.tsx @@ -0,0 +1,85 @@ +import { Button, EmptyCard } from '@/ui'; +import { useState } from 'react'; +import { objectToSnake } from 'ts-case-convert'; +import FichePicto from '../../PlansActions/FicheAction/FichesLiees/FichePicto'; +import ModaleFichesLiees from '../../PlansActions/FicheAction/FichesLiees/ModaleFichesLiees'; +import FichesActionListe from '../../PlansActions/ToutesLesFichesAction/FichesActionListe'; +import { + useFichesActionLiees, + useUpdateFichesActionLiees, +} from '../Indicateur/useFichesActionLiees'; +import { TIndicateurDefinition } from '../types'; + +type Props = { + definition: TIndicateurDefinition; + isReadonly: boolean; +}; + +const FichesLiees = ({ definition, isReadonly }: Props) => { + const [isModalOpen, setIsModalOpen] = useState(false); + + const { data: fiches } = useFichesActionLiees(definition); + const fichesLiees = (fiches ? objectToSnake(fiches) : []).map((f) => f.id); + + const { mutate: updateFichesActionLiees } = + useUpdateFichesActionLiees(definition); + + const isEmpty = fiches.length === 0; + + return ( + <> + {isEmpty ? ( + } + title="Aucune fiche action de vos plans d'actions n'est liée !" + isReadonly={isReadonly} + actions={[ + { + children: 'Lier une fiche action', + icon: 'link', + onClick: () => setIsModalOpen(true), + }, + ]} + size="xs" + /> + ) : ( +
+
+
Fiches des plans liées
+ {!isReadonly && ( + + )} +
+ +
+ )} + + {isModalOpen && ( + + )} + + ); +}; + +export default FichesLiees; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx index a769a2e8b3..f92ad44fe1 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx @@ -5,12 +5,12 @@ import ScrollTopButton from '@/app/ui/buttons/ScrollTopButton'; import { BadgeACompleter } from '@/app/ui/shared/Badge/BadgeACompleter'; import { Badge, Tab, Tabs } from '@/ui'; import ActionsLieesListe from '../../PlansActions/FicheAction/ActionsLiees/ActionsLieesListe'; -import { FichesActionLiees } from '../Indicateur/FichesActionLiees'; import { HeaderIndicateur } from '../Indicateur/detail/HeaderIndicateur'; import { useUpdateIndicateurDefinition } from '../Indicateur/useUpdateIndicateurDefinition'; import BadgeOpenData from '../components/BadgeOpenData'; import { TIndicateurDefinition } from '../types'; import DonneesIndicateur from './DonneesIndicateur'; +import FichesLiees from './FichesLiees'; import IndicateurToolbar from './IndicateurToolbar'; import SousIndicateurs from './SousIndicateurs'; @@ -114,7 +114,10 @@ const IndicateurLayout = ({ ) : ( // Indicateur sans enfant, groupe d'indicateurs avec agrégation, // ou indicateur personnalisé - + {/* Données */} - + )} diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionCard.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionCard.tsx index 968435debd..20bb480b0f 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionCard.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionCard.tsx @@ -7,8 +7,8 @@ import { useState } from 'react'; import { QueryKey } from 'react-query'; import BadgePriorite from '../../components/BadgePriorite'; import BadgeStatut from '../../components/BadgeStatut'; -import { generateTitle } from '../data/utils'; import ModaleSuppression from '../Header/actions/ModaleSuppression'; +import { generateTitle } from '../data/utils'; import FicheActionFooterInfo from './FicheActionFooterInfo'; import ModifierFicheModale from './ModifierFicheModale'; @@ -118,7 +118,7 @@ const FicheActionCard = ({ dataTest="FicheActionCarte" id={carteId} className={classNames( - 'h-full px-4 py-[1.125rem] !gap-3 !text-grey-8 !shadow-none transition', + 'h-full !p-4 !gap-2 !text-grey-8 !shadow-none transition', { 'hover:border-primary-3 hover:!bg-primary-1': !isNotClickable, } @@ -155,23 +155,27 @@ const FicheActionCard = ({ } footer={ // Bas de la carte -
- {/* Date de dernière modification */} - {!!ficheAction.modifiedAt && ( - - Modifié {getModifiedSince(ficheAction.modifiedAt)} - - )} - +
{/* Personnes pilote et date de fin prévisionnelle */} + + {/* Date de dernière modification */} + {!!ficheAction.modifiedAt && ( + <> +
+ + Modifié {getModifiedSince(ficheAction.modifiedAt)} + + + )}
} > diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionFooterInfo.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionFooterInfo.tsx index bf3b0bdd01..734eb6f8d5 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionFooterInfo.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/Carte/FicheActionFooterInfo.tsx @@ -1,80 +1,109 @@ import { Personne } from '@/api/collectivites'; import { getTextFormattedDate } from '@/app/utils/formatUtils'; +import { Tag } from '@/domain/collectivites'; import { Icon, Tooltip } from '@/ui'; import classNames from 'classnames'; import { isBefore, startOfToday } from 'date-fns'; -import { Fragment } from 'react'; type FicheActionFooterInfoProps = { pilotes: Personne[] | null | undefined; + services: Tag[] | null | undefined; dateDeFin: string | null | undefined; ameliorationContinue: boolean | null | undefined; }; const FicheActionFooterInfo = ({ pilotes, + services, dateDeFin, ameliorationContinue, }: FicheActionFooterInfoProps) => { const hasPilotes = !!pilotes && pilotes.length > 0; + const hasServices = !!services && services.length > 0; const hasDateDeFin = !!dateDeFin; - if (!hasPilotes && !hasDateDeFin && !ameliorationContinue) return null; - const isLate = hasDateDeFin && isBefore(new Date(dateDeFin), startOfToday()); return ( -
- {/* Personnes pilote */} - {hasPilotes && ( - - - {pilotes[0].nom} - {pilotes.length > 1 && ( - - {pilotes.map((pilote, i) => ( -
  • {pilote.nom}
  • - ))} - - } - > - - +{pilotes.length - 1} - -
    - )} -
    - )} - +
    {/* Date de fin prévisionnelle */} {!!dateDeFin && ( - - {hasPilotes &&
    } - - - {getTextFormattedDate({ - date: dateDeFin, - shortMonth: true, - })} - - + + + {getTextFormattedDate({ + date: dateDeFin, + shortMonth: true, + })} + )} {/* Action récurrente */} {!hasDateDeFin && ameliorationContinue && ( - - {hasPilotes &&
    } - - - Tous les ans + + + Tous les ans + + )} + + {/* Personnes pilote */} + {hasPilotes && ( + <> + {(hasDateDeFin || ameliorationContinue) && ( +
    + )} + + + {pilotes[0].nom} + {pilotes.length > 1 && ( + + {pilotes.map((pilote, i) => ( +
  • {pilote.nom}
  • + ))} + + } + > + + +{pilotes.length - 1} + +
    + )} +
    + + )} + + {/* Services pilote */} + {hasServices && ( + <> + {(hasDateDeFin || ameliorationContinue || hasPilotes) && ( +
    + )}{' '} + + + {services[0].nom} + {services.length > 1 && ( + + {services.map((service, i) => ( +
  • {service.nom}
  • + ))} + + } + > + + +{services.length - 1} + +
    + )}
    - + )}
    ); diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/FichesLiees/ModaleFichesLiees.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/FichesLiees/ModaleFichesLiees.tsx index 83ec36f38f..4d5e9dd7f6 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/FichesLiees/ModaleFichesLiees.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/FicheAction/FichesLiees/ModaleFichesLiees.tsx @@ -5,7 +5,7 @@ import { useEffect, useState } from 'react'; type ModaleFichesLieesProps = { isOpen: boolean; setIsOpen: (opened: boolean) => void; - currentFicheId: number; + currentFicheId: number | null; linkedFicheIds: number[]; updateLinkedFicheIds: (ficheIds: number[]) => void; }; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx index 0754829b50..71324e0e9e 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { FetchOptions, @@ -23,6 +23,7 @@ import FilterBadges, { CustomFilterBadges, useFiltersToBadges, } from '@/app/ui/shared/filters/filter-badges'; +import _ from 'lodash'; import { FicheResume } from 'packages/api/src/plan-actions'; import ActionsGroupeesMenu from '../ActionsGroupees/ActionsGroupeesMenu'; import EmptyFichePicto from '../FicheAction/FichesLiees/EmptyFichePicto'; @@ -60,7 +61,7 @@ const sortByOptions: sortByOptionsType[] = [ ]; type Props = { - settings: (openState: OpenState) => React.ReactNode; + settings?: (openState: OpenState) => React.ReactNode; filtres: Filtre; customFilterBadges?: CustomFilterBadges; resetFilters?: () => void; @@ -68,6 +69,7 @@ type Props = { sortSettings?: SortFicheActionSettings; enableGroupedActions?: boolean; isReadOnly?: boolean; + containeClassName?: string; }; /** Liste de fiches action avec tri et options de fitlre */ @@ -82,9 +84,12 @@ const FichesActionListe = ({ maxNbOfCards = 15, enableGroupedActions = false, isReadOnly, + containeClassName, }: Props) => { const collectiviteId = useCollectiviteId(); + const filtresLocal = useRef(filtres); + const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [isGroupedActionsOn, setIsGroupedActionsOn] = useState(false); const [selectedFiches, setSelectedFiches] = useState([]); @@ -153,7 +158,10 @@ const FichesActionListe = ({ }; useEffect(() => { - setCurrentPage(1); + if (!_.isEqual(filtres, filtresLocal.current)) { + filtresLocal.current = filtres; + setCurrentPage(1); + } }, [filtres]); useEffect(() => { @@ -198,9 +206,14 @@ const FichesActionListe = ({ )} {hasFiches && ( - <> -
    -
    +
    +
    +
    {/** Tri */}
    @@ -257,7 +270,7 @@ const FichesActionListe = ({ displaySize="sm" /> {/** Bouton d'édition des filtres (une modale avec bouton ou un ButtonMenu) */} - {settings({ + {settings?.({ isOpen: isSettingsOpen, setIsOpen: setIsSettingsOpen, })} @@ -365,7 +378,7 @@ const FichesActionListe = ({ )} - +
    )} ); From 722e56c287390f0f44d0c6513b0dc7a8ed26957b Mon Sep 17 00:00:00 2001 From: Marine Heckler Date: Fri, 10 Jan 2025 17:01:05 +0100 Subject: [PATCH 4/5] =?UTF-8?q?Onglet=20actions=20li=C3=A9es=20sur=20la=20?= =?UTF-8?q?page=20indicateur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Indicateurs/detail/ActionsLiees.tsx | 33 +++++++++++++++++++ .../Indicateurs/detail/IndicateurLayout.tsx | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ActionsLiees.tsx diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ActionsLiees.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ActionsLiees.tsx new file mode 100644 index 0000000000..b6245a5076 --- /dev/null +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/ActionsLiees.tsx @@ -0,0 +1,33 @@ +import { EmptyCard } from '@/ui'; +import ActionPicto from '../../PlansActions/FicheAction/ActionsLiees/ActionPicto'; +import ActionsLieesListe from '../../PlansActions/FicheAction/ActionsLiees/ActionsLieesListe'; + +type Props = { + actionsIds: string[]; +}; + +const ActionsLiees = ({ actionsIds }: Props) => { + const isEmpty = actionsIds.length === 0; + + return isEmpty ? ( + } + title="Aucune action des référentiels n'est liée !" + size="xs" + /> + ) : ( +
    +
    +
    + Actions du référentiel associées +
    +
    + +
    + ); +}; + +export default ActionsLiees; diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx index f92ad44fe1..ce4ec2df68 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/Indicateurs/detail/IndicateurLayout.tsx @@ -4,11 +4,11 @@ import { useCurrentCollectivite } from '@/app/core-logic/hooks/useCurrentCollect import ScrollTopButton from '@/app/ui/buttons/ScrollTopButton'; import { BadgeACompleter } from '@/app/ui/shared/Badge/BadgeACompleter'; import { Badge, Tab, Tabs } from '@/ui'; -import ActionsLieesListe from '../../PlansActions/FicheAction/ActionsLiees/ActionsLieesListe'; import { HeaderIndicateur } from '../Indicateur/detail/HeaderIndicateur'; import { useUpdateIndicateurDefinition } from '../Indicateur/useUpdateIndicateurDefinition'; import BadgeOpenData from '../components/BadgeOpenData'; import { TIndicateurDefinition } from '../types'; +import ActionsLiees from './ActionsLiees'; import DonneesIndicateur from './DonneesIndicateur'; import FichesLiees from './FichesLiees'; import IndicateurToolbar from './IndicateurToolbar'; @@ -141,7 +141,7 @@ const IndicateurLayout = ({ {/* Actions des référentiels liées */} {!isPerso ? ( - a.id)} /> From 23681d8e3762568953ca53fd7a0a51f4edff6838 Mon Sep 17 00:00:00 2001 From: Marine Heckler Date: Fri, 17 Jan 2025 14:19:52 +0100 Subject: [PATCH 5/5] Corrections sur la liste des fiches actions --- .../ToutesLesFichesAction/FichesActionListe.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx index 71324e0e9e..c6a3066a65 100644 --- a/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx +++ b/app.territoiresentransitions.react/src/app/pages/collectivite/PlansActions/ToutesLesFichesAction/FichesActionListe.tsx @@ -23,7 +23,7 @@ import FilterBadges, { CustomFilterBadges, useFiltersToBadges, } from '@/app/ui/shared/filters/filter-badges'; -import _ from 'lodash'; +import { isEqual } from 'es-toolkit'; import { FicheResume } from 'packages/api/src/plan-actions'; import ActionsGroupeesMenu from '../ActionsGroupees/ActionsGroupeesMenu'; import EmptyFichePicto from '../FicheAction/FichesLiees/EmptyFichePicto'; @@ -69,7 +69,7 @@ type Props = { sortSettings?: SortFicheActionSettings; enableGroupedActions?: boolean; isReadOnly?: boolean; - containeClassName?: string; + containerClassName?: string; }; /** Liste de fiches action avec tri et options de fitlre */ @@ -84,7 +84,7 @@ const FichesActionListe = ({ maxNbOfCards = 15, enableGroupedActions = false, isReadOnly, - containeClassName, + containerClassName, }: Props) => { const collectiviteId = useCollectiviteId(); @@ -158,7 +158,7 @@ const FichesActionListe = ({ }; useEffect(() => { - if (!_.isEqual(filtres, filtresLocal.current)) { + if (!isEqual(filtres, filtresLocal.current)) { filtresLocal.current = filtres; setCurrentPage(1); } @@ -209,7 +209,7 @@ const FichesActionListe = ({