diff --git a/packages/code-du-travail-frontend/app/plan-du-site/page.tsx b/packages/code-du-travail-frontend/app/plan-du-site/page.tsx
new file mode 100644
index 0000000000..db72080e47
--- /dev/null
+++ b/packages/code-du-travail-frontend/app/plan-du-site/page.tsx
@@ -0,0 +1,25 @@
+import { Metadata } from "next";
+import { DsfrLayout } from "../../src/modules/layout";
+import { getSitemapData } from "../../src/api";
+import { SiteMap } from "../../src/modules/plan-du-site";
+
+export const metadata: Metadata = {
+ title: "Plan du site",
+ description: "Plan du site du Code du travail numérique",
+};
+
+const getSiteMap = async () => {
+ return getSitemapData();
+};
+
+async function Index() {
+ const data = await getSiteMap();
+
+ return (
+
+
+
+ );
+}
+
+export default Index;
diff --git a/packages/code-du-travail-frontend/cypress/integration/light/plan-du-site/plan-du-site.spec.ts b/packages/code-du-travail-frontend/cypress/integration/light/plan-du-site/plan-du-site.spec.ts
new file mode 100644
index 0000000000..377592ff92
--- /dev/null
+++ b/packages/code-du-travail-frontend/cypress/integration/light/plan-du-site/plan-du-site.spec.ts
@@ -0,0 +1,12 @@
+describe("Plan du site", () => {
+ it("je vois le plan du site", () => {
+ cy.visit("/");
+ cy.get("a").contains("Plan du site").click();
+ cy.findByRole("heading", { level: 1 }).should("have.text", "Plan du site");
+ cy.contains("a", "Page d'accueil");
+ cy.contains("a", "Boîte à outils");
+ cy.contains("a", "Vos fiches pratiques");
+ cy.contains("a", "Votre convention collective");
+ cy.contains("a", "Thèmes");
+ });
+});
diff --git a/packages/code-du-travail-frontend/package.json b/packages/code-du-travail-frontend/package.json
index 1728555f4f..424aa8e3ec 100644
--- a/packages/code-du-travail-frontend/package.json
+++ b/packages/code-du-travail-frontend/package.json
@@ -40,7 +40,7 @@
"@sentry/nextjs": "^8.24.0",
"@socialgouv/cdtn-elasticsearch": "^2.44.2",
"@socialgouv/cdtn-logger": "^2.0.0",
- "@socialgouv/cdtn-types": "^2.48.1",
+ "@socialgouv/cdtn-types": "^2.49.1",
"@socialgouv/cdtn-ui": "workspace:^",
"@socialgouv/cdtn-utils": "workspace:^",
"@socialgouv/fiches-travail-data": "^4.241.0",
@@ -116,7 +116,7 @@
"stylelint-processor-styled-components": "^1.10.0",
"supertest": "^6.3.3",
"testing-library-selector": "0.3.1",
- "typescript": "^5.0.4",
+ "typescript": "^5.5.4",
"xml2js": "^0.6.2"
}
}
diff --git a/packages/code-du-travail-frontend/pages/convention-collective/index.tsx b/packages/code-du-travail-frontend/pages/convention-collective/index.tsx
index be1b6cd1cb..243d520d41 100644
--- a/packages/code-du-travail-frontend/pages/convention-collective/index.tsx
+++ b/packages/code-du-travail-frontend/pages/convention-collective/index.tsx
@@ -81,7 +81,15 @@ export default Page;
export async function getStaticProps() {
try {
- let data = await getAllAgreements();
+ let data = await getAllAgreements([
+ "title",
+ "shortTitle",
+ "description",
+ "url",
+ "slug",
+ "source",
+ "num",
+ ]);
return { props: { ccs: data }, revalidate: REVALIDATE_TIME };
} catch (error) {
console.error(error);
diff --git a/packages/code-du-travail-frontend/pages/integration/[slug].tsx b/packages/code-du-travail-frontend/pages/integration/[slug].tsx
index 1b6d094b22..f8a8638461 100644
--- a/packages/code-du-travail-frontend/pages/integration/[slug].tsx
+++ b/packages/code-du-travail-frontend/pages/integration/[slug].tsx
@@ -48,12 +48,12 @@ const IntegrationPage = (props): JSX.Element => {
const keys = Object.keys(integrationData);
const getModelesList = async () => {
- const modeles = await getAllModeles();
+ const modeles = await getAllModeles(["title", "cdtnId"]);
return modeles
.map((item) => {
return {
- label: item?.title ?? "",
- value: item?.cdtnId ?? "",
+ label: item.title,
+ value: item.cdtnId,
};
})
?.sort((a, b) => a.label.localeCompare(b.label));
@@ -67,10 +67,7 @@ export const getServerSideProps = async ({ query, req }) => {
};
}
const { isModele } = integrationData[slug];
- let selectOptions;
- if (isModele) {
- selectOptions = await getModelesList();
- }
+ const selectOptions = isModele ? await getModelesList() : null;
const hostname: string = req.headers.host;
const [protocol] = req.headers["x-forwarded-proto"]
diff --git a/packages/code-du-travail-frontend/pages/modeles-de-courriers/index.tsx b/packages/code-du-travail-frontend/pages/modeles-de-courriers/index.tsx
index bab9c0963a..e91bffe609 100644
--- a/packages/code-du-travail-frontend/pages/modeles-de-courriers/index.tsx
+++ b/packages/code-du-travail-frontend/pages/modeles-de-courriers/index.tsx
@@ -105,7 +105,14 @@ function Modeles(props) {
export async function getStaticProps() {
try {
- const data = await getAllModeles();
+ const data = await getAllModeles([
+ "title",
+ "slug",
+ "description",
+ "source",
+ "breadcrumbs",
+ "cdtnId",
+ ]);
return { props: { data }, revalidate: REVALIDATE_TIME };
} catch (error) {
console.error(error);
diff --git a/packages/code-du-travail-frontend/pages/plan-du-site.tsx b/packages/code-du-travail-frontend/pages/plan-du-site.tsx
deleted file mode 100644
index 2a90013ef9..0000000000
--- a/packages/code-du-travail-frontend/pages/plan-du-site.tsx
+++ /dev/null
@@ -1,220 +0,0 @@
-import {
- Container,
- PageTitle,
- Section,
- theme,
- Wrapper,
-} from "@socialgouv/cdtn-ui";
-import * as Sentry from "@sentry/nextjs";
-import React from "react";
-import Metas from "../src/common/Metas";
-import { Layout } from "../src/layout/Layout";
-import styled from "styled-components";
-import Link from "next/link";
-import { getSitemapData, GetSitemapPage } from "../src/api";
-import { getRouteBySource, SOURCES } from "@socialgouv/cdtn-utils";
-import { REVALIDATE_TIME } from "../src/config";
-
-const PlanDuSite = ({
- tools,
- modeles,
- contributions,
- agreements,
- themes,
- informations,
-}: GetSitemapPage) => {
- return (
-
-
-
-
- Plan du site
-
- Page d'accueil
-
- Boîte à outils
-
- {tools.map((tool) => (
-
-
- {tool.title}
-
-
- ))}
-
-
-
- Modèles de documents
-
- {modeles.map((modele) => (
-
-
- {modele?.title}
-
-
- ))}
-
-
-
- Contenus éditoriaux
-
- {informations.map((information) => (
-
-
- {information.title}
-
-
- ))}
-
-
-
- Vos fiches pratiques
-
- {contributions.map((contribution) => (
-
-
- {contribution.generic.title}
-
-
- {contribution.agreements.map((c) => (
-
-
- {c.title}
-
-
- ))}
-
-
- ))}
-
-
-
-
- Votre convention collective
-
-
- {agreements.map((agreement) => (
-
-
- {agreement.title}
-
-
- ))}
-
-
-
- Thèmes
-
- {themes.map((theme) => (
-
-
- {theme.title}
-
- {theme.children && theme.children.length > 0 && (
-
- {theme.children.map((subTheme) => (
-
-
- {subTheme.label}
-
- {subTheme.children &&
- subTheme.children.length > 0 && (
-
- {subTheme.children.map((item) => (
-
-
- {item.label}
-
-
- ))}
-
- )}
-
- ))}
-
- )}
-
- ))}
-
-
-
-
-
-
- );
-};
-
-export async function getStaticProps() {
- let data;
- try {
- data = await getSitemapData();
- } catch (e) {
- console.error(e);
- Sentry.captureException(e);
- }
-
- return {
- props: {
- themes: data?.themes ?? [],
- tools: data?.tools ?? [],
- contributions: data?.contributions ?? [],
- modeles: data?.modeles ?? [],
- agreements: data?.agreements ?? [],
- informations: data?.informations ?? [],
- },
- revalidate: REVALIDATE_TIME,
- };
-}
-
-export const StyledSection = styled.div`
- margin-top: ${theme.spacings.base};
-`;
-
-export const StyledLi = styled.li`
- font-size: ${theme.fonts.sizes.small};
-
- a {
- font-weight: 400;
- display: block;
- padding: 5px 0;
- }
-`;
-
-export default PlanDuSite;
diff --git a/packages/code-du-travail-frontend/pages/themes/index.tsx b/packages/code-du-travail-frontend/pages/themes/index.tsx
index 5b5e52f5f4..6840d64929 100644
--- a/packages/code-du-travail-frontend/pages/themes/index.tsx
+++ b/packages/code-du-travail-frontend/pages/themes/index.tsx
@@ -15,7 +15,7 @@ import Metas from "../../src/common/Metas";
import { REVALIDATE_TIME } from "../../src/config";
import { Layout } from "../../src/layout/Layout";
import { LinkedTile } from "../../src/common/tiles/LinkedTile";
-import { getAllThemes } from "../../src/api";
+import { getRootThemes } from "../../src/api";
const SubThemes = ({ children = [] }) => {
return (
@@ -73,8 +73,14 @@ const ThemesPage = ({ children = [] }) => (
export async function getStaticProps() {
try {
- const data = await getAllThemes();
- return { props: { children: data.children }, revalidate: REVALIDATE_TIME };
+ const data = await getRootThemes([
+ "icon",
+ "children",
+ "title",
+ "slug",
+ "position",
+ ]);
+ return { props: { children: data }, revalidate: REVALIDATE_TIME };
} catch (error) {
console.error(error);
return {
diff --git a/packages/code-du-travail-frontend/src/api/modules/agreements/__tests__/service.test.ts b/packages/code-du-travail-frontend/src/api/modules/agreements/__tests__/service.test.ts
index 739f85a11a..803da95428 100644
--- a/packages/code-du-travail-frontend/src/api/modules/agreements/__tests__/service.test.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/agreements/__tests__/service.test.ts
@@ -9,7 +9,10 @@ import {
describe("Agreements", () => {
it("getAllAgreements", async () => {
- const result = await getAllAgreements();
+ const result = await getAllAgreements(
+ ["title", "shortTitle", "description", "url", "slug", "source", "num"],
+ "shortTitle"
+ );
expect(result).toMatchSnapshot();
});
it("getBySlugsAgreements", async () => {
diff --git a/packages/code-du-travail-frontend/src/api/modules/agreements/queries.ts b/packages/code-du-travail-frontend/src/api/modules/agreements/queries.ts
index 126dac7822..aebaceccc4 100644
--- a/packages/code-du-travail-frontend/src/api/modules/agreements/queries.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/agreements/queries.ts
@@ -1,16 +1,7 @@
import { SOURCES } from "@socialgouv/cdtn-utils";
-export const getAllAgreementsWithContributions = () => {
+export const getAllAgreementsQuery = () => {
return {
- _source: [
- "title",
- "shortTitle",
- "description",
- "url",
- "slug",
- "source",
- "num",
- ],
query: {
bool: {
filter: [
diff --git a/packages/code-du-travail-frontend/src/api/modules/agreements/service.ts b/packages/code-du-travail-frontend/src/api/modules/agreements/service.ts
index 1f2241bb0b..ac623df46f 100644
--- a/packages/code-du-travail-frontend/src/api/modules/agreements/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/agreements/service.ts
@@ -3,24 +3,31 @@ import {
getAgreementBySlug,
getAgreementsByIds,
getAgreementsBySlugs,
- getAllAgreementsWithContributions,
+ getAllAgreementsQuery,
} from "./queries";
import { ElasticSearchItem } from "../../types";
import { AgreementDoc, ElasticAgreement } from "@socialgouv/cdtn-types";
-import { nonNullable } from "@socialgouv/modeles-social";
+import {orderByAlpha} from "../../utils/sort";
-export const getAllAgreements = async (): Promise => {
- const body = getAllAgreementsWithContributions();
+export const getAllAgreements = async (
+ fields: K[],
+ sortBy?: K
+): Promise[]> => {
+ const body = getAllAgreementsQuery();
- const response = await elasticsearchClient.search({
- body,
+ const response = await elasticsearchClient.search>({
+ ...body,
+ _source: fields,
index: elasticDocumentsIndex,
});
- return response.hits.hits
+ const data = response.hits.hits
.map(({ _source }) => _source)
- .filter(nonNullable)
- .sort(orderByAlpha);
+ .filter((item) => item !== undefined);
+ if (sortBy) {
+ data.sort((a, b) => orderByAlpha(a, b, sortBy));
+ }
+ return data;
};
export const getBySlugsAgreements = async (
@@ -62,9 +69,3 @@ export const getBySlugAgreements = async (slug: string) => {
return { ...response.hits.hits[0]._source };
};
-
-const orderByAlpha = (a, b) => {
- return a.shortTitle.localeCompare(b.shortTitle, "fr", {
- ignorePunctuation: true,
- });
-};
diff --git a/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/__snapshots__/service.test.ts.snap b/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/__snapshots__/service.test.ts.snap
index c99ba54fa1..c9334bac05 100644
--- a/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/__snapshots__/service.test.ts.snap
+++ b/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/__snapshots__/service.test.ts.snap
@@ -1,32 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Contributions getAllContributions 1`] = `
-[
- {
- "agreements": [],
- "generic": {
- "idcc": "0000",
- "slug": "les-conges-pour-evenements-familiaux",
- "title": "Les congés pour événements familiaux",
- },
- },
- {
- "agreements": [
- {
- "idcc": "0044",
- "slug": "44-quand-le-salarie-a-t-il-droit-a-une-prime-danciennete-quel-est-son-montant",
- "title": "Quand le salarié a-t-il droit à une prime d’ancienneté ? Quel est son montant ?",
- },
- ],
- "generic": {
- "idcc": "0000",
- "slug": "quand-le-salarie-a-t-il-droit-a-une-prime-danciennete-quel-est-son-montant",
- "title": "Quand le salarié a-t-il droit à une prime d’ancienneté ? Quel est son montant ?",
- },
- },
-]
-`;
-
exports[`Contributions getByIdsContributions 1`] = `
[
{
diff --git a/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/service.test.ts b/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/service.test.ts
index 977a17c73c..08e2dd4741 100644
--- a/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/service.test.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/contributions/__tests__/service.test.ts
@@ -1,11 +1,9 @@
/** @jest-environment node */
import {
- getAllContributionsGroupByQuestion,
getByIdsContributions,
getGenericContributionsGroupByThemes,
} from "../service";
-import { getAllAgreements } from "../../agreements";
describe("Contributions", () => {
it("getGenericContributions", async () => {
@@ -17,10 +15,4 @@ describe("Contributions", () => {
const result = await getByIdsContributions(["eba7a4592f"]);
expect(result).toMatchSnapshot();
});
-
- it("getAllContributions", async () => {
- const agreements = await getAllAgreements();
- const result = await getAllContributionsGroupByQuestion(agreements);
- expect(result).toMatchSnapshot();
- });
});
diff --git a/packages/code-du-travail-frontend/src/api/modules/contributions/fetch.ts b/packages/code-du-travail-frontend/src/api/modules/contributions/fetch.ts
index 0a06df0c78..b08e90c6d7 100644
--- a/packages/code-du-travail-frontend/src/api/modules/contributions/fetch.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/contributions/fetch.ts
@@ -1,11 +1,23 @@
+import { ContributionElasticDocument } from "@socialgouv/cdtn-types";
import { elasticDocumentsIndex, elasticsearchClient } from "../../utils";
import { getAllContributions } from "./queries";
-export const fetchAllContributions = async () => {
+export const fetchAllContributions = async <
+ K extends keyof ContributionElasticDocument
+>(
+ fields: K[]
+): Promise[]> => {
const body = getAllContributions();
- return await elasticsearchClient.search({
- body,
+ const result = await elasticsearchClient.search<
+ Pick
+ >({
+ ...body,
+ _source: fields,
index: elasticDocumentsIndex,
});
+
+ return result.hits.hits
+ .map(({ _source }) => _source)
+ .filter((source) => source !== undefined);
};
diff --git a/packages/code-du-travail-frontend/src/api/modules/contributions/queries.ts b/packages/code-du-travail-frontend/src/api/modules/contributions/queries.ts
index 73899674ab..88e2935fe0 100644
--- a/packages/code-du-travail-frontend/src/api/modules/contributions/queries.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/contributions/queries.ts
@@ -2,7 +2,6 @@ import { SOURCES } from "@socialgouv/cdtn-utils";
export const getAllContributions = () => {
return {
- _source: ["title", "shortTitle", "slug", "idcc"],
query: {
bool: {
filter: [
diff --git a/packages/code-du-travail-frontend/src/api/modules/contributions/service.ts b/packages/code-du-travail-frontend/src/api/modules/contributions/service.ts
index 1793cff09f..045d7aadde 100644
--- a/packages/code-du-travail-frontend/src/api/modules/contributions/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/contributions/service.ts
@@ -4,6 +4,7 @@ import { fetchAllContributions } from "./fetch";
import { ElasticSearchItem } from "../../types";
import { ElasticAgreement } from "@socialgouv/cdtn-types";
+
export const getGenericContributionsGroupByThemes = async () => {
const body = getAllGenericsContributions();
@@ -20,41 +21,6 @@ export const getGenericContributionsGroupByThemes = async () => {
.reduce(groupByThemes, {});
};
-const isGeneric = (contrib) => contrib.idcc === "0000";
-
-function getTitle(agreements: ElasticAgreement[], contrib) {
- const idcc = contrib.idcc ?? contrib.slug.split("-")[0];
- const agreement = agreements.find((a) => a.num === parseInt(idcc));
- return agreement
- ? `${contrib.title} - ${agreement.shortTitle}`
- : contrib.title;
-}
-
-export const getAllContributionsGroupByQuestion = async (
- agreements: ElasticAgreement[]
-) => {
- const response = await fetchAllContributions();
- const all = response.hits.hits.map(({ _source }) => _source);
- const allGenerics = all
- .filter(isGeneric)
- .sort((a, b) => a.title.localeCompare(b.title));
-
- return allGenerics.map((generic) => {
- return {
- generic: generic,
- agreements: all
- .filter((contrib) => {
- return !isGeneric(contrib) && contrib.slug.includes(generic.slug);
- })
- .map((contrib) => {
- contrib.title = getTitle(agreements, contrib);
- return contrib;
- })
- .sort((a, b) => a.title.localeCompare(b.title)),
- };
- });
-};
-
export const getByIdsContributions = async (
ids: string[]
): Promise => {
diff --git a/packages/code-du-travail-frontend/src/api/modules/home/service.ts b/packages/code-du-travail-frontend/src/api/modules/home/service.ts
index bf0e4495fb..82682f1a8f 100644
--- a/packages/code-du-travail-frontend/src/api/modules/home/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/home/service.ts
@@ -3,7 +3,7 @@ import { getByIdsAgreements } from "../agreements";
import { getByIdsContributions } from "../contributions";
import { getBySlugHighlights } from "../highlights";
import { getByIdsModeles } from "../modeles";
-import { getAllThemes } from "../themes";
+import { getRootThemes } from "../themes";
import { getToolsByIds } from "../tools";
export type GetHomePage = {
@@ -16,7 +16,13 @@ export type GetHomePage = {
};
export const getHomeData = async (): Promise => {
- const themes = await getAllThemes();
+ const themes = await getRootThemes([
+ "icon",
+ "children",
+ "title",
+ "slug",
+ "position",
+ ]);
const highlights = await getBySlugHighlights("homepage");
const tools = await getToolsByIds([
"d7ad36850a", // simulateur-embauche
diff --git a/packages/code-du-travail-frontend/src/api/modules/informations/queries.ts b/packages/code-du-travail-frontend/src/api/modules/informations/queries.ts
index 5de097f745..96cc87b94d 100644
--- a/packages/code-du-travail-frontend/src/api/modules/informations/queries.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/informations/queries.ts
@@ -2,7 +2,6 @@ import { SOURCES } from "@socialgouv/cdtn-utils";
export const fetchInformations = () => {
return {
- _source: ["title", "slug"],
query: {
bool: {
filter: [
diff --git a/packages/code-du-travail-frontend/src/api/modules/informations/service.ts b/packages/code-du-travail-frontend/src/api/modules/informations/service.ts
index ef5ec5b96a..13a991db6c 100644
--- a/packages/code-du-travail-frontend/src/api/modules/informations/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/informations/service.ts
@@ -1,18 +1,29 @@
+import { EditorialContentElasticDocument } from "@socialgouv/cdtn-types";
import { elasticDocumentsIndex, elasticsearchClient } from "../../utils";
import { fetchInformations } from "./queries";
+import { orderByAlpha } from "../../utils/sort";
-export const getAllInformations = async () => {
+export const getAllInformations = async <
+ K extends keyof EditorialContentElasticDocument
+>(
+ fields: K[],
+ sortBy?: K
+): Promise[]> => {
const body = fetchInformations();
- const response = await elasticsearchClient.search({
- body,
+ const response = await elasticsearchClient.search<
+ Pick
+ >({
+ ...body,
+ _source: fields,
index: elasticDocumentsIndex,
});
- return response.hits.hits
+
+ const data = response.hits.hits
.map(({ _source }) => _source)
- .sort((infoA, infoB) => {
- return infoA.title.localeCompare(infoB.title, "fr", {
- ignorePunctuation: true,
- });
- });
+ .filter((source) => source !== undefined);
+ if (sortBy) {
+ return data.sort((a, b) => orderByAlpha(a, b, sortBy));
+ }
+ return data;
};
diff --git a/packages/code-du-travail-frontend/src/api/modules/modeles/__tests__/service.test.ts b/packages/code-du-travail-frontend/src/api/modules/modeles/__tests__/service.test.ts
index 8d671117fd..efe6867864 100644
--- a/packages/code-du-travail-frontend/src/api/modules/modeles/__tests__/service.test.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/modeles/__tests__/service.test.ts
@@ -9,7 +9,14 @@ import {
describe("Modeles", () => {
it("getAllModeles", async () => {
- const result = await getAllModeles();
+ const result = await getAllModeles([
+ "title",
+ "slug",
+ "description",
+ "source",
+ "breadcrumbs",
+ "cdtnId",
+ ]);
expect(result).toMatchSnapshot();
});
it("getBySlugsModeles", async () => {
diff --git a/packages/code-du-travail-frontend/src/api/modules/modeles/queries.ts b/packages/code-du-travail-frontend/src/api/modules/modeles/queries.ts
index 4604b46a2b..27f9ff64f3 100644
--- a/packages/code-du-travail-frontend/src/api/modules/modeles/queries.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/modeles/queries.ts
@@ -2,14 +2,6 @@ import { SOURCES } from "@socialgouv/cdtn-utils";
export function getModeles() {
return {
- _source: [
- "title",
- "slug",
- "description",
- "source",
- "breadcrumbs",
- "cdtnId",
- ],
query: {
bool: {
filter: [
diff --git a/packages/code-du-travail-frontend/src/api/modules/modeles/service.ts b/packages/code-du-travail-frontend/src/api/modules/modeles/service.ts
index a52c6e7086..35ecab239d 100644
--- a/packages/code-du-travail-frontend/src/api/modules/modeles/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/modeles/service.ts
@@ -1,6 +1,6 @@
import {
DocumentElasticWithSource,
- MailTemplate,
+ MailTemplateDoc,
} from "@socialgouv/cdtn-types";
import { ElasticSearchItem } from "../../types";
import {
@@ -15,17 +15,24 @@ import {
getModelesBySlugs,
} from "./queries";
-export const getAllModeles = async () => {
+export const getAllModeles = async <
+ K extends keyof DocumentElasticWithSource
+>(
+ fields: K[]
+): Promise, K>[]> => {
const body = getModeles();
const response = await elasticsearchClient.search<
- DocumentElasticWithSource
+ DocumentElasticWithSource<
+ Pick, K>
+ >
>({
- body,
+ ...body,
+ _source: fields,
index: elasticDocumentsIndex,
});
- return response.hits.hits.length > 0
- ? response.hits.hits.map(({ _source }) => _source)
- : [];
+ return response.hits.hits
+ .map(({ _source }) => _source)
+ .filter((source) => source !== undefined);
};
export const getBySlugsModeles = async (
diff --git a/packages/code-du-travail-frontend/src/api/modules/sitemap/__tests__/service.test.ts b/packages/code-du-travail-frontend/src/api/modules/sitemap/__tests__/service.test.ts
index 6fa608b989..dd00d2b817 100644
--- a/packages/code-du-travail-frontend/src/api/modules/sitemap/__tests__/service.test.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/sitemap/__tests__/service.test.ts
@@ -4,73 +4,39 @@ import { getSitemapData } from "../service";
jest.mock("../../contributions/fetch", () => ({
fetchAllContributions: async () => {
- return Promise.resolve({
- hits: {
- total: 6,
- hits: [
- {
- _source: {
- idcc: "0044",
- type: "content",
- content: "content1",
- title: "title1",
- source: "contribution",
- slug: "44-slug-content1",
- },
- },
- {
- _source: {
- idcc: "0000",
- type: "content",
- content: "content1",
- title: "title1",
- source: "contribution",
- slug: "slug-content1",
- },
- },
- {
- _source: {
- idcc: "0016",
- type: "content",
- content: "content1",
- title: "title1",
- source: "contribution",
- slug: "16-slug-content1",
- },
- },
- {
- _source: {
- idcc: "0000",
- type: "content",
- content: "content2",
- title: "title2",
- source: "contribution",
- slug: "slug-content2",
- },
- },
- {
- _source: {
- idcc: "0016",
- type: "content",
- content: "content2",
- title: "title2",
- source: "contribution",
- slug: "16-slug-content2",
- },
- },
- {
- _source: {
- idcc: "0000",
- type: "content",
- content: "content3",
- title: "title3",
- source: "contribution",
- slug: "slug-content3",
- },
- },
- ],
+ return Promise.resolve([
+ {
+ idcc: "0044",
+ title: "title1",
+ slug: "44-slug-content1",
},
- });
+ {
+ idcc: "0000",
+ title: "title1",
+ slug: "slug-content1",
+ },
+ {
+ idcc: "0016",
+ title: "title1",
+ slug: "16-slug-content1",
+ },
+ {
+ idcc: "0000",
+ title: "title2",
+ slug: "slug-content2",
+ },
+ {
+ idcc: "0016",
+ title: "title2",
+ slug: "16-slug-content2",
+ },
+
+ {
+ idcc: "0000",
+ title: "title3",
+ slug: "slug-content3",
+ },
+ ]);
},
}));
@@ -86,69 +52,45 @@ describe("Sitemap", () => {
"informations",
]);
expect(result.tools[0]).toEqual({
- _id: "14",
- displayTool: true,
- slug: "indemnite-licenciement",
- title: "Indemnité de licenciement",
+ root: {
+ slug: "indemnite-licenciement",
+ title: "Indemnité de licenciement",
+ },
});
expect(result.contributions).toEqual([
{
- agreements: [
+ children: [
{
- content: "content1",
- idcc: "0044",
slug: "44-slug-content1",
- source: "contribution",
title: "title1",
- type: "content",
},
{
- content: "content1",
- idcc: "0016",
slug: "16-slug-content1",
- source: "contribution",
title: "title1",
- type: "content",
},
],
- generic: {
- content: "content1",
- idcc: "0000",
+ root: {
slug: "slug-content1",
- source: "contribution",
title: "title1",
- type: "content",
},
},
{
- agreements: [
+ children: [
{
- content: "content2",
- idcc: "0016",
slug: "16-slug-content2",
- source: "contribution",
title: "title2",
- type: "content",
},
],
- generic: {
- content: "content2",
- idcc: "0000",
+ root: {
slug: "slug-content2",
- source: "contribution",
title: "title2",
- type: "content",
},
},
{
- agreements: [],
- generic: {
- content: "content3",
- idcc: "0000",
+ children: [],
+ root: {
slug: "slug-content3",
- source: "contribution",
title: "title3",
- type: "content",
},
},
]);
diff --git a/packages/code-du-travail-frontend/src/api/modules/sitemap/service.ts b/packages/code-du-travail-frontend/src/api/modules/sitemap/service.ts
index 4d76b1df39..30a85738a9 100644
--- a/packages/code-du-travail-frontend/src/api/modules/sitemap/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/sitemap/service.ts
@@ -1,47 +1,116 @@
import {
- Tool,
- EditorialContent,
+ ContributionElasticDocument,
ElasticAgreement,
- MailTemplate,
- DocumentElasticWithSource,
} from "@socialgouv/cdtn-types";
import { getAllAgreements } from "../agreements";
-import { getAllContributionsGroupByQuestion } from "../contributions";
import { getAllModeles } from "../modeles";
-import { getAllThemesAndSubThemes } from "../themes";
+import { getRootThemes } from "../themes";
import { getAllTools } from "../tools";
import { getAllInformations } from "../informations";
-import { ElasticSearchItem } from "../../types";
+import { fetchAllContributions } from "../contributions/fetch";
+import { orderByAlpha } from "../../utils/sort";
-type Information = Pick;
+export type Document = {
+ root: DocumentInfo;
+ children?: DocumentInfo[];
+};
+export type DocumentInfo = {
+ slug: string;
+ title: string;
+};
export type GetSitemapPage = {
- themes: any;
- tools: Tool[];
- modeles: (DocumentElasticWithSource | undefined)[];
- contributions: {
- generic: ElasticSearchItem;
- agreements: ElasticSearchItem[];
- }[];
- agreements: ElasticAgreement[];
- informations: Information[];
+ themes: Document[];
+ tools: Document[];
+ modeles: Document[];
+ contributions: Document[];
+ agreements: Document[];
+ informations: Document[];
};
export const getSitemapData = async () => {
const themes = await getAllThemesAndSubThemes();
- const tools = await getAllTools();
- const modeles = await getAllModeles();
- const agreements = await getAllAgreements();
- const informations = await getAllInformations();
+ const tools = await getAllTools(["slug", "title"]);
+ const modeles = await getAllModeles(["slug", "title"]);
+ const agreements = await getAllAgreements(
+ ["slug", "shortTitle", "num"],
+ "shortTitle"
+ );
+ const informations = await getAllInformations(["slug", "title"], "title");
const contributions = await getAllContributionsGroupByQuestion(agreements);
const response: GetSitemapPage = {
themes,
- tools,
- modeles,
+ tools: tools.map((root) => ({
+ root,
+ })),
+ modeles: modeles.map((root) => ({
+ root,
+ })),
contributions,
- agreements,
- informations,
+ agreements: agreements.map((agg) => ({
+ root: { title: agg.shortTitle, slug: agg.slug },
+ })),
+ informations: informations.map((root) => ({
+ root,
+ })),
};
return response;
};
+
+const getAllContributionsGroupByQuestion = async (
+ agreements: Pick[]
+) => {
+ const all = await fetchAllContributions(["idcc", "title", "slug"]);
+ const allGenerics = all
+ .filter(isGeneric)
+ .sort((a, b) => orderByAlpha(a, b, "title"));
+
+ return allGenerics.map((generic) => {
+ return {
+ root: {
+ title: generic.title,
+ slug: generic.slug,
+ },
+ children: all
+ .filter(
+ (contrib) =>
+ !isGeneric(contrib) && contrib.slug.includes(generic.slug)
+ )
+ .map((contrib) => ({
+ slug: contrib.slug,
+ title: getTitle(agreements, contrib),
+ }))
+ .sort((a, b) => orderByAlpha(a, b, "title")),
+ };
+ });
+};
+
+const isGeneric = (contrib: { idcc: string }) => contrib.idcc === "0000";
+
+const getTitle = (
+ agreements: Pick[],
+ contrib: Pick
+): string => {
+ const agreement = agreements.find((a) => a.num === parseInt(contrib.idcc));
+ return agreement
+ ? `${contrib.title} - ${agreement.shortTitle}`
+ : contrib.title;
+};
+
+export const getAllThemesAndSubThemes = async (): Promise => {
+ const themes = await getRootThemes(["title", "children", "slug"]);
+
+ return themes.map(({ slug, title, children }) => {
+ return {
+ root: {
+ slug,
+ title,
+ },
+ children: children.map((child) => ({
+ title: child.label,
+ slug: child.slug,
+ })),
+ };
+ });
+};
diff --git a/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/__snapshots__/service.test.ts.snap b/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/__snapshots__/service.test.ts.snap
index 71cecd7219..0d73fbb55d 100644
--- a/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/__snapshots__/service.test.ts.snap
+++ b/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/__snapshots__/service.test.ts.snap
@@ -1,65 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Themes getAllThemes 1`] = `
-{
- "children": [
- {
- "children": [
- {
- "label": "Embauche",
- "slug": "embauche",
- },
- {
- "label": "Contrat de travail",
- "slug": "contrat-de-travail",
- },
- ],
- "icon": "Contract",
- "position": 1,
- "slug": "embauche-et-contrat-de-travail",
- "title": "Embauche et contrat de travail",
- },
- {
- "children": [
- {
- "label": "Documents à remettre au salarié",
- "slug": "documents-a-remettre-au-salarie",
- },
- {
- "label": "Démission",
- "slug": "demission",
- },
- {
- "label": "Fin d’un CDD - CTT",
- "slug": "fin-dun-cdd-ctt",
- },
- {
- "label": "Rupture conventionnelle",
- "slug": "rupture-conventionnelle",
- },
- {
- "label": "Licenciement : droits des salariés et procédures",
- "slug": "licenciement-droits-des-salaries-et-procedures",
- },
- {
- "label": "Retraite",
- "slug": "retraite",
- },
- {
- "label": "Autres départs",
- "slug": "autres-departs",
- },
- ],
- "icon": "Depart",
- "position": 8,
- "slug": "depart-de-lentreprise",
- "title": "Départ de l’entreprise",
- },
- ],
-}
-`;
-
-exports[`Themes getAllThemesAndSubThemes 1`] = `
[
{
"children": [
@@ -72,8 +13,6 @@ exports[`Themes getAllThemesAndSubThemes 1`] = `
"slug": "contrat-de-travail",
},
],
- "icon": "Contract",
- "position": 1,
"slug": "embauche-et-contrat-de-travail",
"title": "Embauche et contrat de travail",
},
@@ -86,7 +25,6 @@ exports[`Themes getAllThemesAndSubThemes 1`] = `
{
"label": "Démission",
"slug": "demission",
- "title": "Démission",
},
{
"label": "Fin d’un CDD - CTT",
@@ -109,8 +47,6 @@ exports[`Themes getAllThemesAndSubThemes 1`] = `
"slug": "autres-departs",
},
],
- "icon": "Depart",
- "position": 8,
"slug": "depart-de-lentreprise",
"title": "Départ de l’entreprise",
},
diff --git a/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/service.test.ts b/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/service.test.ts
index 678a1fd4f6..94a8711e13 100644
--- a/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/service.test.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/themes/__tests__/service.test.ts
@@ -1,19 +1,13 @@
/** @jest-environment node */
import {
- getAllThemes,
- getAllThemesAndSubThemes,
+ getRootThemes,
getBySlugThemes,
} from "../service";
describe("Themes", () => {
it("getAllThemes", async () => {
- const result = await getAllThemes();
- expect(result).toMatchSnapshot();
- });
-
- it("getAllThemesAndSubThemes", async () => {
- const result = await getAllThemesAndSubThemes();
+ const result = await getRootThemes(["title", "slug", "children"]);
expect(result).toMatchSnapshot();
});
diff --git a/packages/code-du-travail-frontend/src/api/modules/themes/queries.ts b/packages/code-du-travail-frontend/src/api/modules/themes/queries.ts
index f941a24731..ffafbcb786 100644
--- a/packages/code-du-travail-frontend/src/api/modules/themes/queries.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/themes/queries.ts
@@ -1,8 +1,7 @@
import { SOURCES } from "@socialgouv/cdtn-utils";
-export function getAllThemesQuery() {
+export function getRootThemesQuery() {
return {
- _source: ["icon", "children", "title", "slug", "position"],
query: {
bool: {
filter: [
@@ -42,7 +41,6 @@ export function getThemeBySlugQuery(slug: string) {
export function getThemeBySlugsQuery(slugs: string[]) {
return {
- _source: ["title", "slug"],
query: {
bool: {
filter: [
diff --git a/packages/code-du-travail-frontend/src/api/modules/themes/service.ts b/packages/code-du-travail-frontend/src/api/modules/themes/service.ts
index 97cd155dc5..e418cf4f0f 100644
--- a/packages/code-du-travail-frontend/src/api/modules/themes/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/themes/service.ts
@@ -1,53 +1,25 @@
+import { elasticDocumentsIndex, elasticsearchClient } from "../../utils";
import {
- elasticsearchClient,
- elasticDocumentsIndex,
- NotFoundError,
-} from "../../utils";
-import {
- getAllThemesQuery,
+ getRootThemesQuery,
getThemeBySlugQuery,
getThemeBySlugsQuery,
} from "./queries";
-
-export const getAllThemes = async () => {
- const body: any = getAllThemesQuery();
- const response = await elasticsearchClient.search({
- body,
- index: elasticDocumentsIndex,
- });
- return {
- children: response.hits.hits.map((t) => t._source),
- };
-};
-
-export const getAllThemesAndSubThemes = async () => {
- const body: any = getAllThemesQuery();
- const response = await elasticsearchClient.search({
- body,
+import { ThemeElasticDocument } from "@socialgouv/cdtn-types/build/elastic/theme";
+
+export const getRootThemes = async (
+ fields: K[]
+): Promise[]> => {
+ const body = getRootThemesQuery();
+ const response = await elasticsearchClient.search<
+ Pick
+ >({
+ ...body,
+ _source: fields,
index: elasticDocumentsIndex,
});
- const themes = response.hits.hits.map((t) => t._source);
- // for each theme of themes, we need to get slug of children
- const childrenSlugs = themes.flatMap((theme) =>
- theme.children.map((child) => child.slug)
- );
- const data = await getBySlugsThemes(childrenSlugs).catch(() => {
- return [];
- });
- const themesWithChildren = themes.map((theme) => {
- const children = theme.children.map((child) => {
- const childWithContent = data.find((d: any) => d.slug === child.slug);
- return {
- ...child,
- ...childWithContent,
- };
- });
- return {
- ...theme,
- children,
- };
- });
- return themesWithChildren;
+ return response.hits.hits
+ .map((t) => t._source)
+ .filter((item) => item !== undefined);
};
export const getBySlugThemes = async (slug: string) => {
@@ -69,23 +41,21 @@ export const getBySlugThemes = async (slug: string) => {
};
};
-export const getBySlugsThemes = async (slugs: string[]) => {
+export const getBySlugsThemes = async (
+ slugs: string[],
+ fields: K[]
+): Promise[]> => {
const body: any = getThemeBySlugsQuery(slugs);
- const response = await elasticsearchClient.search({
- body,
+ const response = await elasticsearchClient.search<
+ Pick
+ >({
+ ...body,
+ _source: fields,
index: elasticDocumentsIndex,
});
- if (response.hits.hits.length === 0) {
- throw new NotFoundError({
- message: `There is no theme that match ${slugs.join(",")}`,
- name: "THEME_NOT_FOUND",
- cause: null,
- });
- }
-
- const themes = response.hits.hits.map(({ _source }) => _source);
-
- return themes;
+ return response.hits.hits
+ .map(({ _source }) => _source)
+ .filter((item) => item !== undefined);
};
diff --git a/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/__snapshots__/service.test.ts.snap b/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/__snapshots__/service.test.ts.snap
index 8cdb3ec6df..b7fa3a40ce 100644
--- a/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/__snapshots__/service.test.ts.snap
+++ b/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/__snapshots__/service.test.ts.snap
@@ -3,19 +3,16 @@
exports[`Tools getAllTools 1`] = `
[
{
- "_id": "14",
"displayTool": true,
"slug": "indemnite-licenciement",
"title": "Indemnité de licenciement",
},
{
- "_id": "13",
"displayTool": true,
"slug": "preavis-demission",
"title": "Préavis de démission",
},
{
- "_id": "27",
"displayTool": true,
"slug": "heures-recherche-emploi",
"title": "Heures d'absence pour rechercher un emploi",
diff --git a/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/service.test.ts b/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/service.test.ts
index b194e95a40..e66508c327 100644
--- a/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/service.test.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/tools/__tests__/service.test.ts
@@ -10,7 +10,7 @@ import {
describe("Tools", () => {
it("getAllTools", async () => {
- const result = await getAllTools();
+ const result = await getAllTools(["slug", "title", "displayTool"]);
expect(result).toMatchSnapshot();
});
it("getToolsBySlugs", async () => {
diff --git a/packages/code-du-travail-frontend/src/api/modules/tools/queries.ts b/packages/code-du-travail-frontend/src/api/modules/tools/queries.ts
index 7de885a42f..bd7ba6a377 100644
--- a/packages/code-du-travail-frontend/src/api/modules/tools/queries.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/tools/queries.ts
@@ -1,18 +1,34 @@
+import { Tool } from "@socialgouv/cdtn-types";
+
export const getAllToolsQuery = () => {
return {
- _source: ["slug", "title", "displayTool"],
query: {
bool: {
must: [
- { term: { isPublished: true } },
- { term: { source: "outils" } },
+ {
+ term: {
+ isPublished: true,
+ },
+ },
+ {
+ term: {
+ source: "outils",
+ },
+ },
+ {
+ term: {
+ displayTool: true,
+ },
+ },
],
},
},
size: 50,
sort: [
{
- order: "asc",
+ order: {
+ order: "asc",
+ },
},
],
};
diff --git a/packages/code-du-travail-frontend/src/api/modules/tools/service.ts b/packages/code-du-travail-frontend/src/api/modules/tools/service.ts
index 7e425ffa6c..70976da8a8 100644
--- a/packages/code-du-travail-frontend/src/api/modules/tools/service.ts
+++ b/packages/code-du-travail-frontend/src/api/modules/tools/service.ts
@@ -1,16 +1,19 @@
import { Tool } from "@socialgouv/cdtn-types";
import {
- elasticsearchClient,
elasticDocumentsIndex,
+ elasticsearchClient,
NotFoundError,
} from "../../utils";
-import { getTools, getAllToolsQuery } from "./queries";
+import { getAllToolsQuery, getTools } from "./queries";
import { SearchHit } from "@elastic/elasticsearch/lib/api/types";
-export const getAllTools = async (): Promise => {
+export const getAllTools = async (
+ fields: K[]
+): Promise[]> => {
const body: any = getAllToolsQuery();
- const response = await elasticsearchClient.search({
- body,
+ const response = await elasticsearchClient.search>({
+ ...body,
+ _source: fields,
index: elasticDocumentsIndex,
});
if (response.hits.hits.length === 0) {
@@ -21,8 +24,8 @@ export const getAllTools = async (): Promise => {
});
}
return response.hits.hits
- .map(({ _id, _source }) => ({ ..._source, _id }))
- .filter((tool) => tool.displayTool);
+ .map(({ _source }) => _source)
+ .filter((source) => source !== undefined);
};
export const getToolsByIdsAndSlugs = async (
diff --git a/packages/code-du-travail-frontend/src/api/utils/sort.ts b/packages/code-du-travail-frontend/src/api/utils/sort.ts
new file mode 100644
index 0000000000..565f81da5a
--- /dev/null
+++ b/packages/code-du-travail-frontend/src/api/utils/sort.ts
@@ -0,0 +1,8 @@
+export const orderByAlpha = (a: T, b: T, field: keyof T): number => {
+ const valueA = String(a[field]);
+ const valueB = String(b[field]);
+
+ return valueA.localeCompare(valueB, "fr", {
+ ignorePunctuation: true,
+ });
+};
diff --git a/packages/code-du-travail-frontend/src/modules/plan-du-site/__tests__/PlanDuSite.test.tsx b/packages/code-du-travail-frontend/src/modules/plan-du-site/__tests__/PlanDuSite.test.tsx
new file mode 100644
index 0000000000..b3079d05ae
--- /dev/null
+++ b/packages/code-du-travail-frontend/src/modules/plan-du-site/__tests__/PlanDuSite.test.tsx
@@ -0,0 +1,38 @@
+import { render } from "@testing-library/react";
+import React from "react";
+import { SiteMap } from "..";
+import type { Document } from "../../../api";
+
+describe("", () => {
+ it("should match snapshot", () => {
+ const sampleData: Document[] = [
+ {
+ root: {
+ slug: "slug-test",
+ title: "Test title",
+ },
+ children: [
+ {
+ title: "Content 1",
+ slug: "content-1",
+ },
+ {
+ title: "Content 2",
+ slug: "content-2",
+ },
+ ],
+ },
+ ];
+ const { container } = render(
+
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/packages/code-du-travail-frontend/src/modules/plan-du-site/__tests__/__snapshots__/PlanDuSite.test.tsx.snap b/packages/code-du-travail-frontend/src/modules/plan-du-site/__tests__/__snapshots__/PlanDuSite.test.tsx.snap
new file mode 100644
index 0000000000..b6717a98f0
--- /dev/null
+++ b/packages/code-du-travail-frontend/src/modules/plan-du-site/__tests__/__snapshots__/PlanDuSite.test.tsx.snap
@@ -0,0 +1,269 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` should match snapshot 1`] = `
+
+
+
+
+ Plan du site
+
+
+
+
+
+
+ Contenus éditoriaux
+
+
+
+
+
+
+
+
+
+`;
diff --git a/packages/code-du-travail-frontend/src/modules/plan-du-site/index.tsx b/packages/code-du-travail-frontend/src/modules/plan-du-site/index.tsx
new file mode 100644
index 0000000000..370dedd867
--- /dev/null
+++ b/packages/code-du-travail-frontend/src/modules/plan-du-site/index.tsx
@@ -0,0 +1,126 @@
+import { fr } from "@codegouvfr/react-dsfr";
+import { Document } from "../../api";
+import React from "react";
+import Link from "next/link";
+import { getRouteBySource, SourceKeys, SOURCES } from "@socialgouv/cdtn-utils";
+import { Container } from "../layout/Container";
+
+type Props = {
+ themes: Document[];
+ tools: Document[];
+ modeles: Document[];
+ contributions: Document[];
+ agreements: Document[];
+ informations: Document[];
+};
+
+type SectionProps = {
+ title: string;
+ url?: string;
+ detail?: {
+ source: SourceKeys;
+ docs: Document[];
+ };
+};
+
+const SiteMapSection = ({ title, url, detail }: SectionProps) => (
+
+ {url ? (
+
+
{title}
+
+ ) : (
+
+ {title}
+
+ )}
+
+ {detail && (
+
+ {detail.docs.map(({ root, children }) => (
+ -
+
+ {root.title}
+
+ {children && (
+
+ {children.map((doc) => (
+ -
+
+ {doc.title}
+
+
+ ))}
+
+ )}
+
+ ))}
+
+ )}
+
+);
+
+export const SiteMap = ({
+ tools,
+ modeles,
+ contributions,
+ agreements,
+ informations,
+ themes,
+}: Props) => (
+
+
+ Plan du site
+
+
+
+
+
+
+
+
+
+);
diff --git a/packages/code-du-travail-modeles/package.json b/packages/code-du-travail-modeles/package.json
index 71693c0842..145b4f803a 100644
--- a/packages/code-du-travail-modeles/package.json
+++ b/packages/code-du-travail-modeles/package.json
@@ -28,7 +28,7 @@
"jest": "^29.7.0",
"lint-staged": "^13.0.0",
"nodemon": "^2.0.12",
- "typescript": "^5.0.4",
+ "typescript": "^5.5.4",
"typescript-eslint": "^8.0.0"
},
"scripts": {
diff --git a/packages/code-du-travail-utils/package.json b/packages/code-du-travail-utils/package.json
index ce5a4e4657..c15fe0c79c 100644
--- a/packages/code-du-travail-utils/package.json
+++ b/packages/code-du-travail-utils/package.json
@@ -21,6 +21,6 @@
"@swc/core": "^1.3.36",
"@swc/jest": "^0.2.36",
"jest": "^29.7.0",
- "typescript": "^5.0.4"
+ "typescript": "^5.5.4"
}
}
diff --git a/packages/react-ui/package.json b/packages/react-ui/package.json
index 92d1be2dfd..2a9a25323b 100644
--- a/packages/react-ui/package.json
+++ b/packages/react-ui/package.json
@@ -71,7 +71,7 @@
"stylelint-order": "^5.0.0",
"stylelint-processor-styled-components": "^1.10.0",
"svgo": "^2.3.1",
- "typescript": "^5.0.4",
+ "typescript": "^5.5.4",
"vite": "^4.3.9"
},
"license": "MIT",
diff --git a/yarn.lock b/yarn.lock
index 3e2c049083..7e00b1eadf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1884,7 +1884,7 @@ __metadata:
"@sentry/nextjs": ^8.24.0
"@socialgouv/cdtn-elasticsearch": ^2.44.2
"@socialgouv/cdtn-logger": ^2.0.0
- "@socialgouv/cdtn-types": ^2.48.1
+ "@socialgouv/cdtn-types": ^2.49.1
"@socialgouv/cdtn-ui": "workspace:^"
"@socialgouv/cdtn-utils": "workspace:^"
"@socialgouv/fiches-travail-data": ^4.241.0
@@ -1954,7 +1954,7 @@ __metadata:
stylelint-processor-styled-components: ^1.10.0
supertest: ^6.3.3
testing-library-selector: 0.3.1
- typescript: ^5.0.4
+ typescript: ^5.5.4
uuid: ^9.0.0
xml2js: ^0.6.2
xss: ^1.0.10
@@ -6010,10 +6010,10 @@ __metadata:
languageName: node
linkType: hard
-"@socialgouv/cdtn-types@npm:^2.48.1":
- version: 2.48.1
- resolution: "@socialgouv/cdtn-types@npm:2.48.1"
- checksum: 253c83ec90eeef3b2410440510d0ffac9011b2fe8c9707c37fe17c5c52a76bee3ffad31b1f3bd610e4958bc4c9a5ca75264a50a566b9475432c319de3c3da3fe
+"@socialgouv/cdtn-types@npm:^2.49.1":
+ version: 2.49.1
+ resolution: "@socialgouv/cdtn-types@npm:2.49.1"
+ checksum: 50e1ddebe988c24eedafc11ef75b3c29b8c6e047b0ac43d030bea8abb9e14f7651cc4bea18bc75490d93697d184d6353cb7abcd33efc34b7a0ebe58eaee5e987
languageName: node
linkType: hard
@@ -6061,7 +6061,7 @@ __metadata:
stylelint-order: ^5.0.0
stylelint-processor-styled-components: ^1.10.0
svgo: ^2.3.1
- typescript: ^5.0.4
+ typescript: ^5.5.4
use-onclickoutside: ^0.4.0
vite: ^4.3.9
languageName: unknown
@@ -6074,7 +6074,7 @@ __metadata:
"@swc/core": ^1.3.36
"@swc/jest": ^0.2.36
jest: ^29.7.0
- typescript: ^5.0.4
+ typescript: ^5.5.4
languageName: unknown
linkType: soft
@@ -6140,7 +6140,7 @@ __metadata:
lint-staged: ^13.0.0
nodemon: ^2.0.12
publicodes: 1.0.0-beta.60
- typescript: ^5.0.4
+ typescript: ^5.5.4
typescript-eslint: ^8.0.0
yaml: ^2.0.0
languageName: unknown
@@ -25128,13 +25128,13 @@ __metadata:
languageName: node
linkType: hard
-"typescript@npm:^5.0.4":
- version: 5.1.3
- resolution: "typescript@npm:5.1.3"
+"typescript@npm:^5.5.4":
+ version: 5.5.4
+ resolution: "typescript@npm:5.5.4"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
- checksum: d9d51862d98efa46534f2800a1071a613751b1585dc78884807d0c179bcd93d6e9d4012a508e276742f5f33c480adefc52ffcafaf9e0e00ab641a14cde9a31c7
+ checksum: b309040f3a1cd91c68a5a58af6b9fdd4e849b8c42d837b2c2e73f9a4f96a98c4f1ed398a9aab576ee0a4748f5690cf594e6b99dbe61de7839da748c41e6d6ca8
languageName: node
linkType: hard
@@ -25158,13 +25158,13 @@ __metadata:
languageName: node
linkType: hard
-"typescript@patch:typescript@^5.0.4#~builtin":
- version: 5.1.3
- resolution: "typescript@patch:typescript@npm%3A5.1.3#~builtin::version=5.1.3&hash=5da071"
+"typescript@patch:typescript@^5.5.4#~builtin":
+ version: 5.5.4
+ resolution: "typescript@patch:typescript@npm%3A5.5.4#~builtin::version=5.5.4&hash=b45daf"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
- checksum: 6f0a9dca6bf4ce9dcaf4e282aade55ef4c56ecb5fb98d0a4a5c0113398815aea66d871b5611e83353e5953a19ed9ef103cf5a76ac0f276d550d1e7cd5344f61e
+ checksum: fc52962f31a5bcb716d4213bef516885e4f01f30cea797a831205fc9ef12b405a40561c40eae3127ab85ba1548e7df49df2bcdee6b84a94bfbe3a0d7eff16b14
languageName: node
linkType: hard