From 1ff72813c3397e5c739ac3028ce2e6e90b55fca0 Mon Sep 17 00:00:00 2001 From: Imen Chermiti Date: Fri, 19 Jan 2024 13:11:06 +0100 Subject: [PATCH] feat: add search by region& add anchors --- .../Enterprise/Infos/EnterpriseInfos.js | 62 +++++----- .../Enterprise/Infos/Finances/Finances.js | 4 +- .../Establishment/Direccte/Controles.gql.js | 68 +++++------ .../Establishment/Direccte/Controles.js | 2 +- .../components/DataSheets/Sidebar/Sidebar.js | 37 ++++++ .../DataSheets/Sidebar/sidebar.scss | 3 - .../Search/Filters/LocationFilter.js | 111 +++++++++++++----- src/client/src/containers/Search/Search.js | 15 ++- .../services/LocationSearch/LocationSearch.js | 20 +++- 9 files changed, 216 insertions(+), 106 deletions(-) diff --git a/src/client/src/components/DataSheets/Sections/Enterprise/Infos/EnterpriseInfos.js b/src/client/src/components/DataSheets/Sections/Enterprise/Infos/EnterpriseInfos.js index 0593a0467..f8446f661 100644 --- a/src/client/src/components/DataSheets/Sections/Enterprise/Infos/EnterpriseInfos.js +++ b/src/client/src/components/DataSheets/Sections/Enterprise/Infos/EnterpriseInfos.js @@ -42,40 +42,40 @@ const EnterpriseInfos = ({ enterprise: baseEntreprise }) => { const location = useLocation(); useEffect(() => { const hash = window.location.hash; - if (location.pathname.includes("enterprise") && hash === "#mandataires") { - const checkAndScroll = () => { - const element = document.getElementById("mandataires"); - const headerOffset = - document.getElementById("header")?.offsetHeight || 0; // Dynamic header height - console.log(document.getElementById("header")); - if (element) { - const position = element.offsetTop - headerOffset; // Subtract header height - window.scrollTo({ - behavior: "smooth", - top: position, - }); - return true; - } - return false; - }; - - // Check if element is available and scroll to it - if (!checkAndScroll()) { - // If element is not available, set an interval to check again + + const checkAndScroll = (elementId) => { + const element = document.getElementById(elementId); + const headerOffset = document.getElementById("header")?.offsetHeight || 0; + if (element) { + const position = element.offsetTop - headerOffset; + window.scrollTo({ + behavior: "smooth", + top: position, + }); + return true; + } + return false; + }; + + const setupScroll = (targetId) => { + if (!checkAndScroll(targetId)) { const interval = setInterval(() => { - if (checkAndScroll()) { - clearInterval(interval); // Clear interval once the element is found + if (checkAndScroll(targetId)) { + clearInterval(interval); } - }, 100); // Check every 100ms + }, 100); + } + window.addEventListener("resize", () => checkAndScroll(targetId)); + return () => + window.removeEventListener("resize", () => checkAndScroll(targetId)); + }; + + if (location.pathname.includes("enterprise")) { + if (hash === "#mandataires") { + return setupScroll("mandataires"); + } else if (hash === "#finance-data") { + return setupScroll("finance-data"); } - - // Add resize event listener - window.addEventListener("resize", checkAndScroll); - - // Clean up interval and remove event listener on component unmount - return () => { - window.removeEventListener("resize", checkAndScroll); - }; } }, [location]); diff --git a/src/client/src/components/DataSheets/Sections/Enterprise/Infos/Finances/Finances.js b/src/client/src/components/DataSheets/Sections/Enterprise/Infos/Finances/Finances.js index e51b0e4d4..4f8d79589 100644 --- a/src/client/src/components/DataSheets/Sections/Enterprise/Infos/Finances/Finances.js +++ b/src/client/src/components/DataSheets/Sections/Enterprise/Infos/Finances/Finances.js @@ -139,7 +139,7 @@ const Finances = ({ siret, siren }) => { }); } return ( - <> +
{hasBilan_K && ( Cette entreprise déclare un bilan consolidé, voir sur{" "} @@ -222,7 +222,7 @@ const Finances = ({ siret, siren }) => { Non disponible

)} - +
); }; diff --git a/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.gql.js b/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.gql.js index 06300ea06..9bac61a79 100644 --- a/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.gql.js +++ b/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.gql.js @@ -4,9 +4,9 @@ import { pipe } from "lodash/fp"; import { BCE_CLIENT } from "../../../../../services/GraphQL/GraphQL"; import { mapQueryResult } from "../../../../../utils/graphql/graphql"; import { - normalizeInteractions3E, - normalizeInteractions3ESRC, - normalizeInteractionsC, + // normalizeInteractions3E, + // normalizeInteractions3ESRC, + // normalizeInteractionsC, normalizeInteractionsT, } from "../../../../../utils/interactions/interactions"; @@ -20,43 +20,43 @@ const controlesQuery = gql` denominationusuelleetablissement } } - fce_interactions_pole_t(where: { siret: { _eq: $siret } }) { - date - intervenant - action_sur - realise_pour - siret - } - fce_interactions_pole_3e(where: { siret: { _eq: $siret } }) { - inspecteurs - date_visite - type_suivi - region - siret - } - fce_interactions_pole_3e_src(where: { siret: { _eq: $siret } }) { - date - libelle_region - siret - type_controle - nature_controle - cible_controle - clos - } + # fce_interactions_pole_t(where: { siret: { _eq: $siret } }) { + # date + # intervenant + # action_sur + # realise_pour + # siret + # } + # fce_interactions_pole_3e(where: { siret: { _eq: $siret } }) { + # inspecteurs + # date_visite + # type_suivi + # region + # siret + # } + # fce_interactions_pole_3e_src(where: { siret: { _eq: $siret } }) { + # date + # libelle_region + # siret + # type_controle + # nature_controle + # cible_controle + # clos + # } } `; const normalizeResponsesToInteraction = ({ - fce_interactions_pole_3e, - fce_interactions_pole_3e_src, - fce_interactions_pole_c, + // fce_interactions_pole_3e, + // fce_interactions_pole_3e_src, + // fce_interactions_pole_c, fce_interactions_pole_t, }) => ({ - interactions_pole_3e: normalizeInteractions3E(fce_interactions_pole_3e), - interactions_pole_3e_src: normalizeInteractions3ESRC( - fce_interactions_pole_3e_src - ), - interactions_pole_c: normalizeInteractionsC(fce_interactions_pole_c), + // interactions_pole_3e: normalizeInteractions3E(fce_interactions_pole_3e), + // interactions_pole_3e_src: normalizeInteractions3ESRC( + // fce_interactions_pole_3e_src + // ), + // interactions_pole_c: normalizeInteractionsC(fce_interactions_pole_c), interactions_pole_t: normalizeInteractionsT(fce_interactions_pole_t), }); diff --git a/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.js b/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.js index d0b226072..a87a57a8d 100644 --- a/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.js +++ b/src/client/src/components/DataSheets/Sections/Establishment/Direccte/Controles.js @@ -45,7 +45,7 @@ const Controles = ({ siret }) => {
Dernier contrôle ou visite au cours des 24 derniers mois (Pôle - T, Pôle C, Pôle 3E) + T, Pôle C, Pôle ES)
diff --git a/src/client/src/components/DataSheets/Sidebar/Sidebar.js b/src/client/src/components/DataSheets/Sidebar/Sidebar.js index 7bfca8667..4ccf0a3ff 100644 --- a/src/client/src/components/DataSheets/Sidebar/Sidebar.js +++ b/src/client/src/components/DataSheets/Sidebar/Sidebar.js @@ -92,6 +92,43 @@ const Sidebar = ({ }} > Entreprise + {!isEntrepriseDisplayed && ( +
+
+ + + + + {"Données financières"} + +
+
+ + + + + {"Mandataires"} + +
+
+ + + + + {"..."} + +
+
+ )} {isEntrepriseDisplayed && (
diff --git a/src/client/src/components/DataSheets/Sidebar/sidebar.scss b/src/client/src/components/DataSheets/Sidebar/sidebar.scss index c7af99c19..1db9fc484 100644 --- a/src/client/src/components/DataSheets/Sidebar/sidebar.scss +++ b/src/client/src/components/DataSheets/Sidebar/sidebar.scss @@ -183,7 +183,4 @@ $border-color: var(--border-color); margin-bottom: $spacing-3; } } - - - } diff --git a/src/client/src/components/Search/Filters/LocationFilter.js b/src/client/src/components/Search/Filters/LocationFilter.js index a339fd8d1..9d62139c9 100644 --- a/src/client/src/components/Search/Filters/LocationFilter.js +++ b/src/client/src/components/Search/Filters/LocationFilter.js @@ -7,13 +7,16 @@ import Config from "../../../services/Config"; import { searchCommune, searchDepartement, + searchRegion, + serachDepartementsByRegion, } from "../../../services/LocationSearch/LocationSearch"; import { selectCustomStyles } from "./customStyles"; const searchLocation = async (query) => { - const [departements, communes] = await Promise.all([ + const [departements, communes, regions] = await Promise.all([ searchDepartement(query), searchCommune(query), + searchRegion(query), ]); const formattedDepartements = departements.map(({ code, nom }) => ({ label: `${nom} (${code})`, @@ -26,10 +29,22 @@ const searchLocation = async (query) => { type: "commune", value: code, })); + const formattedRegions = regions?.map(({ code, nom }) => ({ + label: nom, + type: "region", + value: code, + })); const options = []; if (formattedDepartements.length > 0) { + if (formattedRegions.length > 0) { + options.push({ + label: "REGIONS", + options: formattedRegions, + }); + } + options.push({ label: "DÉPARTEMENTS", options: formattedDepartements, @@ -48,34 +63,72 @@ const searchLocation = async (query) => { const throttledSearch = pDebounce(searchLocation, 300); -const LocationFilter = ({ filters, addFilter, removeFilter }) => ( -
- Zone géographique
} - isMulti - defaultOptions={[]} - loadOptions={throttledSearch} - onChange={(location) => { - location ? addFilter("location", location) : removeFilter("location"); - }} - components={{ - IndicatorSeparator: () => null, - }} - loadingMessage={() => "Chargement..."} - noOptionsMessage={(term) => - term.inputValue.length >= Config.get("advancedSearch").minTerms - ? "Aucun résultat" - : `Veuillez saisir au moins ${ - Config.get("advancedSearch").minTerms - } caractères` - } - value={filters?.location || []} - styles={selectCustomStyles} - /> -
-); +const LocationFilter = ({ filters, addFilter, removeFilter }) => { + const addAddress = (locations) => { + Promise.all( + locations.map(async (loc) => { + const { type, value, label, regions } = loc; + + if (type === "region" && !regions) { + try { + const data = await serachDepartementsByRegion(value); + const departementsResult = data.map(({ code, nom }) => ({ + label: `${nom} (${code})`, + type: "departement", + value: code, + })); + + return { + label: label, + regions: departementsResult, + type: type, + value: value, + }; + } catch (error) { + console.error("Error fetching departements:", error); + return loc; // Return the original location in case of an error + } + } else { + return loc; // Return the original location for non-region types + } + }) + ).then((updatedLocations) => { + // Update the filter with the new array of locations + addFilter("location", updatedLocations); + }); + }; + + return ( +
+ Zone géographique
+ } + isMulti + defaultOptions={[]} + loadOptions={throttledSearch} + onChange={(location) => { + location ? addAddress(location) : removeFilter("location"); + }} + components={{ + IndicatorSeparator: () => null, + }} + loadingMessage={() => "Chargement..."} + noOptionsMessage={(term) => + term.inputValue.length >= Config.get("advancedSearch").minTerms + ? "Aucun résultat" + : `Veuillez saisir au moins ${ + Config.get("advancedSearch").minTerms + } caractères` + } + value={filters?.location || []} + styles={selectCustomStyles} + /> +
+ ); +}; LocationFilter.propTypes = { addFilter: PropTypes.func.isRequired, diff --git a/src/client/src/containers/Search/Search.js b/src/client/src/containers/Search/Search.js index a13dff64e..9d5f1438f 100644 --- a/src/client/src/containers/Search/Search.js +++ b/src/client/src/containers/Search/Search.js @@ -25,12 +25,18 @@ const XLSX_DOC_TYPE = const formatLocationFilter = (filters) => { const locationFilters = groupBy(filters.location, "type"); + const codesCommunes = locationFilters?.commune?.map(prop("value")) || []; + const departements = [ + ...(locationFilters?.departement?.map(prop("value")) || []), + ...(locationFilters?.region?.flatMap((regionItem) => + regionItem.regions.map((region) => region.value) + ) || []), + ]; + return { ...omit(filters, "location"), - codesCommunes: normalizeCodeCommunes( - locationFilters?.commune?.map(prop("value")) || [] - ), - departements: locationFilters?.departement?.map(prop("value")) || [], + codesCommunes: normalizeCodeCommunes(codesCommunes), + departements, }; }; @@ -40,7 +46,6 @@ const Search = () => { const { filters, addFilter, removeFilter, removeFilters } = useSearchFilters(); - const { sortField, sortDirection, toggleSortField } = useSort(); const { data, loading, error, makeQuery, query } = useSearchQuery(); diff --git a/src/client/src/services/LocationSearch/LocationSearch.js b/src/client/src/services/LocationSearch/LocationSearch.js index eadcbdf3f..e657c5989 100644 --- a/src/client/src/services/LocationSearch/LocationSearch.js +++ b/src/client/src/services/LocationSearch/LocationSearch.js @@ -4,6 +4,7 @@ const API_BASE_URL = "https://geo.api.gouv.fr"; const DEPARTEMENTS_URL = `${API_BASE_URL}/departements`; const COMMUNES_URL = `${API_BASE_URL}/communes`; +const REGIONS_URL = `${API_BASE_URL}/regions`; const requestApi = async (url, params) => { try { @@ -24,13 +25,28 @@ const searchDepartementByName = (nom) => limit: 5, nom, }); - +export const serachDepartementsByRegion = (code) => { + return requestApi(`${REGIONS_URL}/${code}/departements`); +}; const searchDepartmentByCodePostal = (code) => requestApi(DEPARTEMENTS_URL, { code, fields: "nom,code", limit: 5, }); +const searchRegionByName = (nom) => + requestApi(REGIONS_URL, { + fields: "nom,code", + limit: 5, + nom, + }); + +const searchRegionByCodePostal = (code) => + requestApi(REGIONS_URL, { + code, + fields: "nom,code", + limit: 5, + }); export const searchDepartement = (query) => isNaN(query) @@ -44,6 +60,8 @@ const searchCommuneByName = (nom) => limit: 30, nom, }); +export const searchRegion = (query) => + isNaN(query) ? searchRegionByName(query) : searchRegionByCodePostal(query); const searchCommuneByCodePostal = (codePostal) => requestApi(COMMUNES_URL, {