From ba98367c5a9f55afc9d252b8cf97060d2de884d7 Mon Sep 17 00:00:00 2001
From: Xavier Jp
Date: Wed, 5 Jun 2024 11:40:11 +0200
Subject: [PATCH 1/2] 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);
From 16cbff4b46732d0b33c20286cbcc07b23db9b086 Mon Sep 17 00:00:00 2001
From: Xavier Jp
Date: Wed, 5 Jun 2024 11:54:34 +0200
Subject: [PATCH 2/2] feat: use Link in tabs (#1096)
* feat: use Link in tabs
* feat: improve loadbar behaviour
---------
Co-authored-by: Johan Girod
---
components/header/header-core/index.tsx | 164 +++++++++---------
components/load-bar/index.tsx | 40 +++--
components/load-bar/style.module.css | 9 +
components/title-section/tabs/index.tsx | 21 ++-
.../title-section/tabs/styles.module.css | 3 +-
components/title-section/tabs/tab-link.tsx | 39 +++++
6 files changed, 170 insertions(+), 106 deletions(-)
create mode 100644 components/load-bar/style.module.css
create mode 100644 components/title-section/tabs/tab-link.tsx
diff --git a/components/header/header-core/index.tsx b/components/header/header-core/index.tsx
index 15602f806..742a1ae61 100644
--- a/components/header/header-core/index.tsx
+++ b/components/header/header-core/index.tsx
@@ -30,99 +30,101 @@ export const HeaderCore: React.FC = ({
pathFrom,
}) => {
return (
-