From ba98367c5a9f55afc9d252b8cf97060d2de884d7 Mon Sep 17 00:00:00 2001 From: Xavier Jp Date: Wed, 5 Jun 2024 11:40:11 +0200 Subject: [PATCH] chore: migrate service public to the client (#1098) --- .../sections/service-public-responsables.tsx | 193 ++++++++++-------- .../dirigeants/[slug]/page.tsx | 18 +- .../entreprise/[slug]/page.tsx | 38 ++-- .../etablissement/[slug]/page.tsx | 11 +- .../carte-professionnelle-TP/[slug]/route.ts | 2 +- .../clients/annuaire-service-public/index.ts | 6 +- components/service-public-section/index.tsx | 33 ++- hooks/fetch/service-public.ts | 44 ++++ models/service-public/index.ts | 24 +-- 9 files changed, 211 insertions(+), 158 deletions(-) create mode 100644 hooks/fetch/service-public.ts diff --git a/app/(header-default)/dirigeants/[slug]/_component/sections/service-public-responsables.tsx b/app/(header-default)/dirigeants/[slug]/_component/sections/service-public-responsables.tsx index fe7b392b6..cb6b361d7 100644 --- a/app/(header-default)/dirigeants/[slug]/_component/sections/service-public-responsables.tsx +++ b/app/(header-default)/dirigeants/[slug]/_component/sections/service-public-responsables.tsx @@ -1,99 +1,132 @@ +'use client'; + import { DILA } from '#components/administrations'; import NonRenseigne from '#components/non-renseigne'; -import { DataSection } from '#components/section/data-section'; +import { DataSectionClient } from '#components/section/data-section'; import { FullTable } from '#components/table/full'; import { EAdministration } from '#models/administrations/EAdministration'; -import { IAPINotRespondingError } from '#models/api-not-responding'; -import { IServicePublic } from '#models/service-public'; +import { isAPILoading } from '#models/api-loading'; +import { IUniteLegale } from '#models/core/types'; +import { useFetchServicePublic } from 'hooks/fetch/service-public'; +import SubServicesSection from './service-public-subservices'; -type IProps = { servicePublic: IServicePublic | IAPINotRespondingError }; +export default function ResponsablesServicePublicSection({ + uniteLegale, +}: { + uniteLegale: IUniteLegale; +}) { + const servicePublic = useFetchServicePublic(uniteLegale); -export default function ResponsableSection({ servicePublic }: IProps) { return ( - } - data={servicePublic} - > - {(servicePublic) => ( - <> - {!servicePublic.affectationPersonne ? ( -

- Ce service public n’a pas de responsable enregistré auprès de la{' '} - . -

- ) : ( - <> + <> + } + data={servicePublic} + > + {(servicePublic) => ( + <> + {!servicePublic.affectationPersonne ? (

- Ce service public possède{' '} - {servicePublic.affectationPersonne.length} responsable(s) - enregistré(s) auprès de la - {servicePublic.liens.annuaireServicePublic && ( - <> - {' '} - sur{' '} - - l’Annuaire du service public - - - )} - {servicePublic.liens.organigramme && ( - <> - {' '} - et publie un{' '} - - organigramme - - - )} + Ce service public n’a pas de responsable enregistré dans l’ + + Annuaire de l’administration + .

+ ) : ( + <> +

+ Ce service public possède{' '} + {servicePublic.affectationPersonne.length} responsable(s) + enregistré(s) auprès de la + {servicePublic.liens.annuaireServicePublic && ( + <> + {' '} + sur{' '} + + l’Annuaire du service public + + + )} + {servicePublic.liens.organigramme && ( + <> + {' '} + et publie un{' '} + + organigramme + + + )} + . +

- [ - personne.fonction, - personne.nom ?? , - personne.lienTexteAffectation ? ( - - {personne.lienTexteAffectation.libelle || - 'Voir la nomination'} - - ) : ( - - ), - ])} - /> - - )} - + [ + personne.fonction, + personne.nom ?? , + personne.lienTexteAffectation ? ( + + {personne.lienTexteAffectation.libelle || + 'Voir la nomination'} + + ) : ( + + ), + ])} + /> + + )} + + )} +
+ {!isAPILoading(servicePublic) && ( + )} -
+ ); } const NotFoundInfo = () => (

- Ce service public n’est pas enregistré auprès de la . + Ce service public n’a pas été retrouvé dans l’ + + Annuaire de l’administration + + .

); diff --git a/app/(header-default)/dirigeants/[slug]/page.tsx b/app/(header-default)/dirigeants/[slug]/page.tsx index df671b611..8cd04d5fb 100644 --- a/app/(header-default)/dirigeants/[slug]/page.tsx +++ b/app/(header-default)/dirigeants/[slug]/page.tsx @@ -3,7 +3,7 @@ import { DonneesPriveesSection } from '#components/donnees-privees-section'; import Title from '#components/title-section'; import { FICHE } from '#components/title-section/tabs'; import { estDiffusible } from '#models/core/statut-diffusion'; -import { getServicePublicByUniteLegale } from '#models/service-public'; +import { isServicePublic } from '#models/core/types'; import { EScope, hasRights } from '#models/user/rights'; import { uniteLegalePageDescription, @@ -14,9 +14,8 @@ import extractParamsAppRouter, { AppRouterProps, } from '#utils/server-side-helper/app/extract-params'; import getSession from '#utils/server-side-helper/app/get-session'; -import ResponsableSection from 'app/(header-default)/dirigeants/[slug]/_component/sections/service-public-responsables'; import { DirigeantInformation } from './_component/sections'; -import SubServicesSection from './_component/sections/service-public-subservices'; +import ResponsablesServicePublicSection from './_component/sections/service-public-responsables'; export const generateMetadata = async ( props: AppRouterProps @@ -43,9 +42,6 @@ const DirigeantsPage = async (props: AppRouterProps) => { const { slug, isBot } = extractParamsAppRouter(props); const uniteLegale = await cachedGetUniteLegale(slug, isBot); - const servicePublic = await getServicePublicByUniteLegale(uniteLegale, { - isBot, - }); const session = await getSession(); @@ -57,14 +53,8 @@ const DirigeantsPage = async (props: AppRouterProps) => { ficheType={FICHE.DIRIGEANTS} session={session} /> - {servicePublic ? ( - <> - - - + {isServicePublic(uniteLegale) ? ( + ) : !estDiffusible(uniteLegale) && !hasRights(session, EScope.nonDiffusible) ? ( diff --git a/app/(header-default)/entreprise/[slug]/page.tsx b/app/(header-default)/entreprise/[slug]/page.tsx index e0e88a63a..e0123b9a9 100644 --- a/app/(header-default)/entreprise/[slug]/page.tsx +++ b/app/(header-default)/entreprise/[slug]/page.tsx @@ -1,6 +1,4 @@ import { Metadata } from 'next'; -import { HorizontalSeparator } from '#components-ui/horizontal-separator'; -import BreakPageForPrint from '#components-ui/print-break-page'; import AssociationSection from '#components/association-section'; import CollectiviteTerritorialeSection from '#components/collectivite-territoriale-section'; import { EspaceAgentSummarySection } from '#components/espace-agent-components/summary-section'; @@ -14,11 +12,13 @@ import Title from '#components/title-section'; import { FICHE } from '#components/title-section/tabs'; import UniteLegaleSection from '#components/unite-legale-section'; import UsefulShortcuts from '#components/useful-shortcuts'; -import { isAPINotResponding } from '#models/api-not-responding'; import { estNonDiffusible } from '#models/core/statut-diffusion'; -import { isAssociation, isCollectiviteTerritoriale } from '#models/core/types'; +import { + isAssociation, + isCollectiviteTerritoriale, + isServicePublic, +} from '#models/core/types'; import { getImmatriculationEORI } from '#models/espace-agent/immatriculation-eori'; -import { getServicePublicByUniteLegale } from '#models/service-public'; import { EScope, hasRights } from '#models/user/rights'; import { shouldNotIndex, @@ -55,14 +55,9 @@ export default async function UniteLegalePage(props: AppRouterProps) { const session = await getSession(); const uniteLegale = await cachedGetUniteLegale(slug, isBot, page); - const [servicePublic, immatriculationEORI] = await Promise.all([ - getServicePublicByUniteLegale(uniteLegale, { - isBot, - }), - hasRights(session, EScope.eori) - ? getImmatriculationEORI(uniteLegale.siege.siret, session?.user) - : null, - ]); + const immatriculationEORI = hasRights(session, EScope.eori) + ? await getImmatriculationEORI(uniteLegale.siege.siret, session?.user) + : null; return ( <> @@ -90,19 +85,10 @@ export default async function UniteLegalePage(props: AppRouterProps) { {isCollectiviteTerritoriale(uniteLegale) && ( )} - {servicePublic && ( - - )} - {(isCollectiviteTerritoriale(uniteLegale) || - (servicePublic && !isAPINotResponding(servicePublic))) && ( - <> - - - - )} + {isServicePublic(uniteLegale) && + !isCollectiviteTerritoriale(uniteLegale) && ( + + )} {!isBot && isAssociation(uniteLegale) && ( )} diff --git a/app/(header-default)/etablissement/[slug]/page.tsx b/app/(header-default)/etablissement/[slug]/page.tsx index 81a251eea..be4970a60 100644 --- a/app/(header-default)/etablissement/[slug]/page.tsx +++ b/app/(header-default)/etablissement/[slug]/page.tsx @@ -3,7 +3,7 @@ import { NonDiffusibleSection } from '#components/non-diffusible-section'; import ServicePublicSection from '#components/service-public-section'; import { TitleEtablissementWithDenomination } from '#components/title-section/etablissement'; import { estNonDiffusible } from '#models/core/statut-diffusion'; -import { getServicePublicByEtablissement } from '#models/service-public'; +import { isServicePublic } from '#models/core/types'; import { etablissementPageDescription, etablissementPageTitle, @@ -44,11 +44,6 @@ export default (async function EtablissementPage(props: AppRouterProps) { await cachedEtablissementWithUniteLegale(slug, isBot); const session = await getSession(); - const servicePublic = await getServicePublicByEtablissement( - uniteLegale, - etablissement, - { isBot } - ); return ( <> @@ -73,10 +68,10 @@ export default (async function EtablissementPage(props: AppRouterProps) { usedInEntreprisePage={false} /> )} - {servicePublic && ( + {!isBot && isServicePublic(uniteLegale) && ( )} diff --git a/app/api/data-fetching/espace-agent/carte-professionnelle-TP/[slug]/route.ts b/app/api/data-fetching/espace-agent/carte-professionnelle-TP/[slug]/route.ts index a0fcb9cce..19f04e208 100644 --- a/app/api/data-fetching/espace-agent/carte-professionnelle-TP/[slug]/route.ts +++ b/app/api/data-fetching/espace-agent/carte-professionnelle-TP/[slug]/route.ts @@ -13,7 +13,7 @@ export async function GET( 'CarteProfessionnelleTravauxPublics', slug, EAdministration.FNTP, - EScope.conformite, + EScope.carteProfessionnelleTravauxPublics, async (agentSiret: string) => { const siret = verifySiret(slug as string); const siren = extractSirenFromSiret(siret); diff --git a/clients/open-data-soft/clients/annuaire-service-public/index.ts b/clients/open-data-soft/clients/annuaire-service-public/index.ts index 28b57876c..72ab45100 100644 --- a/clients/open-data-soft/clients/annuaire-service-public/index.ts +++ b/clients/open-data-soft/clients/annuaire-service-public/index.ts @@ -47,7 +47,10 @@ function queryAnnuaireServicePublic(whereQuery: string) { return odsClient( { url: routes.annuaireServicePublic.ods.search, - config: { params: { where: whereQuery }, useCache: true }, + config: { + params: { where: whereQuery }, + useCache: true, + }, }, routes.annuaireServicePublic.ods.metadata ); @@ -82,7 +85,6 @@ const clientAnnuaireServicePublicByIds = async ( ids: string[] ): Promise => { const query = `id="${ids.join('" OR id="')}"`; - const useCache = false; let response = await queryAnnuaireServicePublic(query); if (!response.records.length) { diff --git a/components/service-public-section/index.tsx b/components/service-public-section/index.tsx index cad460914..bb4f6f335 100644 --- a/components/service-public-section/index.tsx +++ b/components/service-public-section/index.tsx @@ -1,28 +1,45 @@ +'use client'; + import { ReactNode } from 'react'; import NonRenseigne from '#components/non-renseigne'; -import { DataSection } from '#components/section/data-section'; +import { DataSectionClient } from '#components/section/data-section'; import { TwoColumnTable } from '#components/table/simple'; import { EAdministration } from '#models/administrations/EAdministration'; -import { IAPINotRespondingError } from '#models/api-not-responding'; -import { IUniteLegale } from '#models/core/types'; +import { IEtablissement, IUniteLegale } from '#models/core/types'; import { IServicePublic } from '#models/service-public'; +import { useFetchServicePublic } from 'hooks/fetch/service-public'; type IProps = { - servicePublic: IServicePublic | IAPINotRespondingError; uniteLegale: IUniteLegale; + etablissement?: IEtablissement; }; export default function ServicePublicSection({ - servicePublic, uniteLegale, + etablissement, }: IProps) { + const servicePublic = useFetchServicePublic(uniteLegale, etablissement); + return ( <> - + Ce service public n’a pas été retrouvé dans l’ + + Annuaire du service public + + . +

+ } > {(servicePublic) => ( <> @@ -44,7 +61,7 @@ export default function ServicePublicSection({ )} )} -
+ ); } diff --git a/hooks/fetch/service-public.ts b/hooks/fetch/service-public.ts new file mode 100644 index 000000000..5b5613d60 --- /dev/null +++ b/hooks/fetch/service-public.ts @@ -0,0 +1,44 @@ +import { EAdministration } from '#models/administrations/EAdministration'; +import { IEtablissement, IUniteLegale } from '#models/core/types'; +import { FetchRessourceException } from '#models/exceptions'; +import { + getServicePublicByEtablissement, + getServicePublicByUniteLegale, +} from '#models/service-public'; +import logErrorInSentry from '#utils/sentry'; +import { useFetchData } from './use-fetch-data'; + +export function useFetchServicePublic( + uniteLegale: IUniteLegale, + etablissement?: IEtablissement +) { + return useFetchData( + { + fetchData: async () => { + if (etablissement) { + return await getServicePublicByEtablissement(etablissement); + } else { + return await getServicePublicByUniteLegale(uniteLegale); + } + }, + administration: EAdministration.DILA, + logError: (e: any) => { + if (e.status) { + // We already log error server side + return; + } + logErrorInSentry( + new FetchRessourceException({ + ressource: 'AnnuaireServicePublic', + administration: EAdministration.DILA, + cause: e, + context: { + siren: uniteLegale.siren, + }, + }) + ); + }, + }, + [uniteLegale] + ); +} diff --git a/models/service-public/index.ts b/models/service-public/index.ts index f9758d94a..b4c444faf 100644 --- a/models/service-public/index.ts +++ b/models/service-public/index.ts @@ -8,11 +8,7 @@ import { APINotRespondingFactory, IAPINotRespondingError, } from '#models/api-not-responding'; -import { - IEtablissement, - IUniteLegale, - isServicePublic, -} from '#models/core/types'; +import { IEtablissement, IUniteLegale } from '#models/core/types'; import { FetchRessourceException } from '#models/exceptions'; import { Siret } from '#utils/helpers'; import logErrorInSentry from '#utils/sentry'; @@ -69,14 +65,9 @@ type IAffectationPersonne = Array<{ }>; export const getServicePublicByUniteLegale = async ( - uniteLegale: IUniteLegale, - options: { isBot: boolean } -): Promise => { + uniteLegale: IUniteLegale +): Promise => { try { - if (options.isBot || !isServicePublic(uniteLegale)) { - return null; - } - return await clientAnnuaireServicePublicBySiret(uniteLegale.siege.siret); } catch (eSiret: any) { try { @@ -91,14 +82,9 @@ export const getServicePublicByUniteLegale = async ( }; export const getServicePublicByEtablissement = async ( - uniteLegale: IUniteLegale, - etablissement: IEtablissement, - options: { isBot: boolean } -): Promise => { + etablissement: IEtablissement +): Promise => { try { - if (options.isBot || !isServicePublic(uniteLegale)) { - return null; - } return await clientAnnuaireServicePublicBySiret(etablissement.siret); } catch (e: any) { return mapToError(e, etablissement.siret);