Skip to content

Commit

Permalink
fix: export xlsx
Browse files Browse the repository at this point in the history
  • Loading branch information
ImenOuidou committed Oct 15, 2024
1 parent e3ca765 commit 52aabd9
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 66 deletions.
2 changes: 2 additions & 0 deletions src/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"react-scrollspy": "^3.4.2",
"react-select": "^5.8.0",
"react-toggle": "^4.1.1",
"react-top-loading-bar": "^2.3.1",
"react-transition-group": "^4.4.1",
"redux": "^4.0.5",
"redux-persist": "^6.0.0",
Expand All @@ -56,6 +57,7 @@
"sass": "^1.79.1",
"smoothscroll-polyfill": "^0.4.3",
"ua-parser-js": "^0.7.21",
"xlsx": "^0.18.5",
"zod": "^3.13.4"
},
"scripts": {
Expand Down
9 changes: 6 additions & 3 deletions src/client/src/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ const App = () => {
const EnterpriseWrapper = () => {
const { siren } = useParams();
const siret = getSirenFromSiret(siren);
const isNotFound = useIsNotFound(siret, siren);
const { isNotFound, loading } = useIsNotFound(siret, siren);

return (
<IEChecker>
Expand All @@ -270,6 +270,7 @@ const EnterpriseWrapper = () => {
isEntrepriseDisplayed
siren={siren}
siret={siret}
loading={loading}
>
<Enterprise siren={siren} />
</CustomLayout>
Expand All @@ -281,7 +282,7 @@ const EnterpriseWrapper = () => {
const EstablishmentWrapper = () => {
const { siret } = useParams();
const siren = getSirenFromSiret(siret);
const isNotFound = useIsNotFound(siret, siren);
const { isNotFound, loading } = useIsNotFound(siret, siren);

return (
<IEChecker>
Expand All @@ -291,6 +292,7 @@ const EstablishmentWrapper = () => {
isEstablishmentDisplayed
siren={siren}
siret={siret}
loading={loading}
>
<LegacyEtablissement siret={siret} />
</CustomLayout>
Expand All @@ -301,7 +303,7 @@ const EstablishmentWrapper = () => {

const ListEstablishmentsWrapper = () => {
const { siren } = useParams();
const isNotFound = useIsNotFound("", siren);
const { isNotFound, loading } = useIsNotFound("", siren);

return (
<IEChecker>
Expand All @@ -310,6 +312,7 @@ const ListEstablishmentsWrapper = () => {
isNotFound={isNotFound}
isEstablishmentsDisplayed
siren={siren}
loading={loading}
>
<ListEtablissements siren={siren} />
</CustomLayout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import NonBorderedTable from "../../SharedComponents/NonBorderedTable/NonBordere
import SortableButton from "../../SharedComponents/NonBorderedTable/SortableButton.jsx";
import SeeDetailsLink from "../../SharedComponents/SeeDetailsLink/SeeDetailsLink.js";
import Subcategory from "../../SharedComponents/Subcategory/index.js";
import { exportToCSV } from "./hooks.js";
import { exportToXLSX } from "./hooks.js";
import { useMarchesPublicWithEtablissements } from "./marchesPublic.gql.js";

const MarchesPublic = ({ siret }) => {
Expand Down Expand Up @@ -56,7 +56,7 @@ const MarchesPublic = ({ siret }) => {
}

const handleExport = () => {
exportToCSV(items, "exported_data.xlsx");
exportToXLSX(items, `commandes_publiques${siret}.xlsx`);
};

const handleColumnChange = (selectedOptions) => {
Expand All @@ -76,7 +76,7 @@ const MarchesPublic = ({ siret }) => {
<BlocTitle
isOpen={accordionOpen}
toggleAccordion={() => setAccordionOpen(!accordionOpen)}
text={" Appels d'offres"}
text={" Commandes publiques"}
/>

{accordionOpen && (
Expand Down Expand Up @@ -326,7 +326,7 @@ const MarchesPublic = ({ siret }) => {
</div>
{items?.length === 0 && (
<div className="data-value is-centred">
{"Aucun appel d'offres connu"}
{"Aucune commande publique connue"}
</div>
)}
</LoadableContent>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as XLSX from "xlsx";

import {
convertirMoisEnAnnees,
joinNoFalsy,
Expand All @@ -10,7 +12,7 @@ import {
getCity,
} from "../../SharedComponents/NonBorderedTable/hooks";

export const exportToCSV = (items, filename = "marches.csv") => {
export const exportToXLSX = (items, filename = "marches.xlsx") => {
const headers = [
"Acheteur",
"Departement",
Expand All @@ -22,9 +24,9 @@ export const exportToCSV = (items, filename = "marches.csv") => {
"Durée",
];

// Create CSV content
const csvContent = [
headers.join(","),
// Créer les données pour l'export
const data = [
headers, // En-têtes
...items.map((marche) => {
const adresse = joinNoFalsy(
[getCodePostal(marche?.etablissement), getCity(marche?.etablissement)],
Expand All @@ -34,24 +36,40 @@ export const exportToCSV = (items, filename = "marches.csv") => {
const acheteurText = getAcheteur(marche);
const acheteurLink = `https://fce.fabrique.social.gouv.fr/establishment/${marche?.acheteur_id}/`;

// Format the link as a clickable hyperlink for French Excel (with semicolon)
const clickableAcheteur = `=HYPERLINK("${acheteurLink}"; "${acheteurText}")`;
// Cette formule sera reconnue dans un fichier .xlsx natif
const clickableAcheteur = {
f: `HYPERLINK("${acheteurLink}", "${acheteurText}")`,
};

return [
`${clickableAcheteur}`,
`"${formatUpperCase(adresse)}"`,
`"${formatUpperCase(marche?.objet)}"`,
`"${formatUpperCase(marche?.cpv_libelle)}"`,
`"${formatUpperCase(marche?.procedure)}"`,
`"${formatChiffre(marche?.montant)}"`,
`"${marche?.dateNotification}"`,
`"${convertirMoisEnAnnees(marche?.dureeMois)}"`,
].join(",");
clickableAcheteur,
formatUpperCase(adresse),
formatUpperCase(marche?.objet),
formatUpperCase(marche?.cpv_libelle),
formatUpperCase(marche?.procedure),
formatChiffre(marche?.montant),
marche?.dateNotification,
convertirMoisEnAnnees(marche?.dureeMois),
];
}),
].join("\n");
];

// Créer un nouveau classeur
const wb = XLSX.utils.book_new();

// Convertir les données en feuille de calcul
const ws = XLSX.utils.aoa_to_sheet(data);

// Ajouter la feuille de calcul au classeur
XLSX.utils.book_append_sheet(wb, ws, "Marchés");

// Générer le fichier XLSX
const wbout = XLSX.write(wb, { bookType: "xlsx", type: "array" });

// Create a Blob and trigger download
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
// Créer un Blob et déclencher le téléchargement
const blob = new Blob([wbout], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
const link = document.createElement("a");
const url = URL.createObjectURL(blob);
link.href = url;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,37 @@ const SortableButton = ({ columnKey, sortConfig, requestSort, label }) => {
onClick={() => requestSort(columnKey)}
>
{label}
{sortConfig?.key === columnKey && (
<>
{sortConfig?.direction === "ascending" ? (
<TopArrow color="#808080" />
) : (
<DownArrow color="#808080" />
)}
</>
)}
<>
<TopArrow
color={
sortConfig?.key === columnKey &&
sortConfig?.direction === "ascending"
? "#000091"
: "#808080"
}
/>

<DownArrow
color={
sortConfig?.key === columnKey &&
sortConfig?.direction === "descending"
? "#000091"
: "#808080"
}
/>
</>
</button>
);
};

SortableButton.propTypes = {
columnKey: Proptypes.string.isRequired,

// Fonction de tri
label: Proptypes.string.isRequired,

// Configuration actuelle de tri
requestSort: Proptypes.func.isRequired,
// Clé pour identifier la colonne
sortConfig: Proptypes.shape({
direction: Proptypes.string,
key: Proptypes.string,
}), // Libellé du bouton
}),
};

export default SortableButton;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemo, useState } from "react";

import { formatSiret } from "../../../../../helpers/utils";
import { formatUpperCase } from "../../../../../utils/entreprise/entreprise";
import { getCodePostal } from "../../../../../utils/establishment/establishment";

// Suppose this function is imported or defined
export const getCity = (marche) =>
Expand All @@ -22,8 +23,9 @@ export const useSortableData = (items, config = null) => {

// Check if the key is "city" and use getCity function
if (sortConfig.key === "city") {
aValue = getCity(a); // Retrieve city using getCity
bValue = getCity(b);
aValue = getCodePostal(a?.etablissement); // Retrieve city using getCity
bValue = getCodePostal(b?.etablissement);
console.log(bValue);
} else if (sortConfig.key === "acheteur") {
aValue = getAcheteur(a);
bValue = getAcheteur(b);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "./../../../../App/variables";

.subcategory {
margin: $spacing-4;
// margin: $spacing-4;

&__header {
display: flex;
Expand Down
30 changes: 10 additions & 20 deletions src/client/src/components/DataSheets/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import classNames from "classnames";
import PropTypes from "prop-types";
import React from "react";
import { connect } from "react-redux";
import { useNavigate } from "react-router-dom";
import { useLocation, useNavigate } from "react-router-dom";

import { useRenderIfSiren } from "../../../helpers/hoc/renderIfSiren.js";
import {
Expand Down Expand Up @@ -32,6 +32,7 @@ const Sidebar = ({
isEntrepriseDisplayed = false,
onOpenUserFeedbackBox,
}) => {
const location = useLocation();
const { loading, data: entreprise, error } = useEstablishmentData();
const navigate = useNavigate();
const shouldNotRender = useRenderIfSiren({
Expand Down Expand Up @@ -63,7 +64,7 @@ const Sidebar = ({
{ label: "Mutations économiques", link: "#muteco" },
{ label: "Aides", link: "#helps" },
{ label: "Agréments", link: "#agrements" },
{ label: "Appels D'offres", link: "#marches" },
{ label: "Commandes publiques", link: "#marches" },
{ label: "Autres etablissements", link: "#autres-etablissements" },
];

Expand All @@ -83,6 +84,7 @@ const Sidebar = ({
onOpenUserFeedbackBox();
navigate.push("#user-feedback");
};

return (
<>
<aside className={` aside-contain`}>
Expand Down Expand Up @@ -143,17 +145,13 @@ const Sidebar = ({
<div key={label}>
<span className="ellipse-span">
<EllipseIconAside
color={
history?.location?.hash == link
? "#000091"
: "#e3e3fd"
}
color={location?.hash == link ? "#000091" : "#e3e3fd"}
/>
</span>
<a
href={link}
className={`${
history?.location?.hash == link ? "active-anchor" : ""
location?.hash == link ? "active-anchor" : ""
}`}
>
{" "}
Expand Down Expand Up @@ -188,18 +186,14 @@ const Sidebar = ({
<span className="ellipse-span">
<EllipseIconAside
color={
history?.location?.hash == link
? "#000091"
: "#e3e3fd"
location?.hash == link ? "#000091" : "#e3e3fd"
}
/>
</span>
<a
href={link}
className={`${
history?.location?.hash == link
? "active-anchor"
: ""
location?.hash == link ? "active-anchor" : ""
}`}
>
{" "}
Expand Down Expand Up @@ -242,17 +236,13 @@ const Sidebar = ({
<div key={label}>
<span className="ellipse-span">
<EllipseIconAside
color={
history?.location?.hash == link
? "#000091"
: "#e3e3fd"
}
color={location?.hash == link ? "#000091" : "#e3e3fd"}
/>
</span>
<a
href={link}
className={`${
history?.location?.hash == link ? "active-anchor" : ""
location?.hash == link ? "active-anchor" : ""
}`}
>
{" "}
Expand Down
4 changes: 2 additions & 2 deletions src/client/src/services/Elastic/elastic.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ export const useIsNotFound = (siret, siren) => {
useEffect(() => {
// Set the isNotFound flag based on data, error, and loading
if (!loading) {
setIsNotFound(error || !data?.results || data?.results?.length === 0);
setIsNotFound(error || data?.results?.length === 0);
}
}, [loading, error, data]);

return isNotFound;
return { isNotFound, loading };
};
Loading

0 comments on commit 52aabd9

Please sign in to comment.