-
-
- {useSearchBar || useLogo ? (
-
- {plugin}
-
-
-
+ {plugin}
+
+
+
+ >
);
};
diff --git a/components/load-bar/index.tsx b/components/load-bar/index.tsx
index eccc79e8b..1fbc0b235 100644
--- a/components/load-bar/index.tsx
+++ b/components/load-bar/index.tsx
@@ -4,27 +4,27 @@ import { useEffect } from 'react';
import constants from '#models/constants';
import { EScope, hasRights } from '#models/user/rights';
import { ISession } from '#models/user/session';
-
+import styles from './style.module.css';
export default function LoadBar({ session }: { session: ISession | null }) {
useEffect(() => {
const loadBar = loadBarFactory();
if (typeof window !== 'undefined') {
- window.addEventListener('beforeunload', loadBar.run);
+ window.addEventListener(
+ 'beforeunload',
+ loadBar.runWithDelay.bind(loadBar)
+ );
+ window.addEventListener('runloadbar', loadBar.runImmediate.bind(loadBar));
+ window.addEventListener('cancelloadbar', loadBar.cancel.bind(loadBar));
}
}, []);
return (
);
@@ -71,8 +71,7 @@ const loadBarFactory = () => {
return {
_currentJobId: '',
_loader: null as HTMLElement | null,
-
- run: async function () {
+ async _run(step: number) {
const jobId = Math.random().toString(16).substring(7);
this._currentJobId = jobId;
@@ -84,14 +83,29 @@ const loadBarFactory = () => {
return;
}
}
-
- for (let w of positions) {
+ this._loader.style.opacity = '1';
+ for (let i = step; i < positions.length; i++) {
// interrupt job if another job has been triggered by another beforeunload event
if (this._currentJobId !== jobId) {
return;
}
- this._loader.style.width = `${w}vw`;
+ this._loader.style.width = `${positions[i]}%`;
+ await wait(200);
+ }
+ },
+ runImmediate() {
+ this._run(2);
+ },
+ runWithDelay() {
+ this._run(0);
+ },
+ async cancel() {
+ this._currentJobId = '';
+ if (this._loader) {
+ this._loader.style.width = '100%';
+ this._loader.style.opacity = '0';
await wait(200);
+ this._loader.style.width = '0';
}
},
};
diff --git a/components/load-bar/style.module.css b/components/load-bar/style.module.css
new file mode 100644
index 000000000..00f8fe94d
--- /dev/null
+++ b/components/load-bar/style.module.css
@@ -0,0 +1,9 @@
+.load-bar {
+ transition: all 200ms ease-in-out;
+ height: 3px;
+ width: 0;
+ opacity: 0;
+ position: fixed;
+ top: 0;
+ z-index: 9999;
+}
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/components/title-section/tabs/index.tsx b/components/title-section/tabs/index.tsx
index 1e648ddfe..d6c5af760 100644
--- a/components/title-section/tabs/index.tsx
+++ b/components/title-section/tabs/index.tsx
@@ -1,3 +1,4 @@
+import Link from 'next/link';
import { PrintNever } from '#components-ui/print-visibility';
import {
checkHasLabelsAndCertificates,
@@ -11,6 +12,7 @@ import {
import { EScope, hasRights } from '#models/user/rights';
import { ISession } from '#models/user/session';
import styles from './styles.module.css';
+import TabLink from './tab-link';
export enum FICHE {
INFORMATION = 'résumé',
@@ -135,30 +137,27 @@ export const Tabs: React.FC<{
noFollow,
width = 'auto',
}) => (
-
- {currentFicheType === ficheType ? label : {label} }
-
+ width={width}
+ />
)
)}
{currentFicheType === FICHE.ETABLISSEMENT && (
<>
-
Fiche établissement
-
+
>
)}
diff --git a/components/title-section/tabs/styles.module.css b/components/title-section/tabs/styles.module.css
index 65c81c7bb..f338691c1 100644
--- a/components/title-section/tabs/styles.module.css
+++ b/components/title-section/tabs/styles.module.css
@@ -56,6 +56,7 @@
}
}
-.titleTabs > a:hover {
+.titleTabs > a:hover,
+.titleTabs > a:focus {
background-color: var(--annuaire-colors-pastelBlue);
}
diff --git a/components/title-section/tabs/tab-link.tsx b/components/title-section/tabs/tab-link.tsx
new file mode 100644
index 000000000..b5441bc4a
--- /dev/null
+++ b/components/title-section/tabs/tab-link.tsx
@@ -0,0 +1,39 @@
+'use client';
+
+import Link from 'next/link';
+import { useEffect } from 'react';
+import styles from './styles.module.css';
+type IProps = {
+ label: string;
+ href: string;
+ noFollow?: boolean;
+ width?: string;
+ active: boolean;
+};
+export default function TabLink({
+ active,
+ href,
+ label,
+ noFollow,
+ width,
+}: IProps) {
+ useEffect(() => {
+ active === false && window.dispatchEvent(new Event('cancelloadbar'));
+ }, [active]);
+ useEffect(() => {
+ window.dispatchEvent(new Event('cancelloadbar'));
+ }, []);
+ return (
+
window.dispatchEvent(new Event('runloadbar'))}
+ prefetch={false}
+ >
+ {active ? label :
{label} }
+
+ );
+}
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);