From 033594b8d0a1e0129daa855a68cdc7f691474bae Mon Sep 17 00:00:00 2001 From: jerem Date: Tue, 4 Feb 2025 14:33:51 +0100 Subject: [PATCH] =?UTF-8?q?feat(atlas):=20am=C3=A9lioration=20de=20l'admin?= =?UTF-8?q?=20avec=20l'ajout=20des=20constantes=20serveur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/admin/dashboard.tsx | 345 +++++-- .../src/pages/admin/{index.tsx => home.tsx} | 0 client/src/pages/admin/routes.tsx | 2 +- .../routes/admin/api-tests/list-indexes.http | 2 +- server/src/routes/admin/index.js | 115 +++ .../api-tests/get-geo-ids-from-search.http | 1 + .../tableaux/atlas/api-tests/get-indexes.http | 1 + server/src/routes/tableaux/atlas/index.js | 850 ++++++++++-------- 8 files changed, 861 insertions(+), 455 deletions(-) rename client/src/pages/admin/{index.tsx => home.tsx} (100%) create mode 100644 server/src/routes/tableaux/atlas/api-tests/get-geo-ids-from-search.http create mode 100644 server/src/routes/tableaux/atlas/api-tests/get-indexes.http diff --git a/client/src/pages/admin/dashboard.tsx b/client/src/pages/admin/dashboard.tsx index 4ff9ccc8..8b72ffd6 100644 --- a/client/src/pages/admin/dashboard.tsx +++ b/client/src/pages/admin/dashboard.tsx @@ -1,3 +1,4 @@ +import { useEffect, useState } from "react"; import { Badge, Breadcrumb, @@ -9,10 +10,12 @@ import { ModalContent, ModalTitle, Row, + Text, Title, } from "@dataesr/dsfr-plus"; import { useParams } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; +import SyntaxHighlighter from "react-syntax-highlighter"; import { queryClient } from "../../main"; import UploadVersion from "./upload-version"; @@ -21,6 +24,14 @@ const { VITE_APP_SERVER_URL } = import.meta.env; export default function Dashboard() { const { dashboardId } = useParams(); + const [constants, setConstants] = useState< + { key: string; value: string; description: string }[] + >([]); + const [indexes, setIndexes] = useState({ + collectionId: "", + versionId: "", + data: [], + }); const { data, isLoading } = useQuery({ queryKey: ["list-dashboards"], @@ -30,13 +41,18 @@ export default function Dashboard() { ), }); + useEffect(() => { + const board = data?.find((dashboard) => dashboard.id === dashboardId); + if (board?.constants) { + setConstants(board.constants); + } + }, [data, dashboardId]); + if (isLoading || !data) { return ( - - Chargement des collections/tables du dashboard {dashboardId} - + Chargement des collections du dashboard {dashboardId} ); @@ -66,6 +82,26 @@ export default function Dashboard() { }); }; + const updateConstant = (key, value) => { + fetch(`${VITE_APP_SERVER_URL}/admin/update-constant`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + dashboardId, + key, + value, + }), + }).then((response) => { + if (response.ok) { + invalidateDashboardQueries(); + } else { + console.log("Erreur lors de la modification de la constante"); + } + }); + }; + const deleteVersion = (collectionId, versionId) => { fetch(`${VITE_APP_SERVER_URL}/admin/delete-version`, { method: "DELETE", @@ -86,6 +122,38 @@ export default function Dashboard() { }); }; + const updateVersionFromDependentCollection = (collectionId) => { + fetch( + `${VITE_APP_SERVER_URL}/admin/update-version-from-dependent-collection`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + dashboardId, + collectionId, + }), + } + ).then((response) => { + if (response.ok) { + invalidateDashboardQueries(); + } else { + console.log("Erreur lors de la mise à jour de la version"); + } + }); + }; + + const showIndexesAside = (collectionId, versionId) => { + fetch(`${VITE_APP_SERVER_URL}/admin/list-indexes?collectionId=${versionId}`) + .then((response) => response.json()) + .then((data) => { + setIndexes({ collectionId, versionId, data }); + }); + }; + + const board = data.find((dashboard) => dashboard.id === dashboardId); + return ( @@ -98,71 +166,172 @@ export default function Dashboard() { - - Liste des collections/tables + <div className="fr-table--sm fr-table fr-table--bordered"> + <div className="fr-table__wrapper"> + <div className="fr-table__container"> + <div className="fr-table__content"> + <table> + <caption>Constantes applicatives du serveur</caption> + <thead> + <tr> + <th>Clé</th> + <th>Valeur</th> + <th>Info</th> + <th /> + </tr> + </thead> + <tbody> + {constants.map((constant) => ( + <tr id="table-sm-row-key-1" data-row-key="1"> + <td>{constant.key}</td> + <td> + <input + onChange={(e) => { + setConstants( + constants.map((el) => + el.key === constant.key + ? { ...el, value: e.target.value } + : el + ) + ); + }} + type="text" + value={constant.value} + /> + </td> + <td>{constant.description}</td> + <td> + <Button + disabled={ + board.constants.find( + (el) => el.key === constant.key + )?.value === constant.value + } + icon="save-line" + onClick={() => { + updateConstant(constant.key, constant.value); + }} + size="sm" + title="Mettre à jour la constante" + variant="text" + /> + </td> + </tr> + ))} + </tbody> + </table> + </div> + </div> + </div> + </div> + <Title as="h2" look="h6"> + Liste des collections - ); diff --git a/client/src/pages/admin/index.tsx b/client/src/pages/admin/home.tsx similarity index 100% rename from client/src/pages/admin/index.tsx rename to client/src/pages/admin/home.tsx diff --git a/client/src/pages/admin/routes.tsx b/client/src/pages/admin/routes.tsx index 1dbf7c38..c63d600d 100644 --- a/client/src/pages/admin/routes.tsx +++ b/client/src/pages/admin/routes.tsx @@ -1,6 +1,6 @@ import { Route, Routes } from "react-router-dom"; -import Home from "./index.tsx"; +import Home from "./home.tsx"; import { Layout } from "../../layout/Layout.tsx"; import Dashboard from "./dashboard.tsx"; diff --git a/server/src/routes/admin/api-tests/list-indexes.http b/server/src/routes/admin/api-tests/list-indexes.http index 1616be67..ee528be2 100644 --- a/server/src/routes/admin/api-tests/list-indexes.http +++ b/server/src/routes/admin/api-tests/list-indexes.http @@ -1 +1 @@ -GET http://localhost:3000/api/admin/list-indexes?collectionId=fr-esr-all-projects-synthese \ No newline at end of file +GET http://localhost:3000/api/admin/list-indexes?collectionId=atlas2024 \ No newline at end of file diff --git a/server/src/routes/admin/index.js b/server/src/routes/admin/index.js index bf80b06d..72e2fec0 100644 --- a/server/src/routes/admin/index.js +++ b/server/src/routes/admin/index.js @@ -5,6 +5,7 @@ import path from "path"; import { db } from "../../services/mongo.js"; import { checkQuery } from "./utils.js"; import uploadVersionRoute from "./upload/upload-version.js"; +import { create } from "domain"; const router = new express.Router(); @@ -60,6 +61,30 @@ router.route("/admin/set-current-version").post(async (req, res) => { res.json(ret); }); +// update constant +router.route("/admin/update-constant").post(async (req, res) => { + const filters = checkQuery(req.body, ["dashboardId", "key", "value"], res); + const { dashboardId, key, value } = filters; + + const response = await db + .collection("boards") + .updateOne( + { id: dashboardId }, + { $set: { "constants.$[elem].value": value } }, + { + arrayFilters: [{ "elem.key": key }] + } + ); + + if (response.matchedCount === 0) { + return res.status(404).json({ error: "No document found" }); + } + + // return current data + const ret = await db.collection("boards").findOne({ id: dashboardId }); + res.json(ret); +}); + // list all uploaded files in files folder router.route("/admin/list-uploaded-files").get((req, res) => { fs.readdir("../files", (err, files) => { @@ -153,4 +178,94 @@ router.route("/admin/delete-uploaded-files").delete((req, res) => { }); }); +// Update a collection from another collection with script execution +router.route('/admin/update-version-from-dependent-collection').post(async (req, res) => { + const filters = checkQuery(req.body, ["dashboardId", "collectionId"], res); + const { dashboardId, collectionId } = filters; + + const board = await db.collection("boards").findOne({ id: dashboardId }); + if (!board) { + return res.status(404).json({ error: "No document found" }); + } + + const dependsOf = board.data.find((d) => d.id === collectionId).dependsOf; + if (!dependsOf) { + return res.status(400).json({ error: "No dependency found" }); + } + + // get the current version of the dependent collection - ex:atlas2024 + const dependentCollectionId = board.data.find((d) => d.id === dependsOf).current; + + +async function run({dependentCollectionId}) { + try { + const atlasCollection = db.collection(dependentCollectionId); + const newCollectionId = 'similar-elements_' + Date.now(); + const similarElementsCollection = db.collection(newCollectionId); + + // await similarElementsCollection.deleteMany({}); + + const years = await atlasCollection.distinct("annee_universitaire"); + const geoIds = await atlasCollection.distinct("geo_id"); + + // for (let i = 0; i < years.length; i++) { + for (let i = years.length-1; i < years.length; i++) { // TODO: remove this line + for (let j = 0; j < geoIds.length; j++) { + const query = { geo_id: geoIds[j], annee_universitaire: years[i], regroupement: 'TOTAL' }; + const data = await atlasCollection.find(query).toArray(); + + const effectifPR = data.filter((item) => item.secteur === 'PR').reduce((acc, item) => acc + item.effectif, 0); + const effectifPU = data.filter((item) => item.secteur === 'PU').reduce((acc, item) => acc + item.effectif, 0); + const pctPR = effectifPR / (effectifPR + effectifPU) * 100; + const pctPU = effectifPU / (effectifPR + effectifPU) * 100; + + const effectifF = data.filter((item) => item.sexe === '2').reduce((acc, item) => acc + item.effectif, 0); + const effectifM = data.filter((item) => item.sexe === '1').reduce((acc, item) => acc + item.effectif, 0); + const pctF = effectifF / (effectifF + effectifM) * 100; + const pctM = effectifM / (effectifF + effectifM) * 100; + + const similarElement = { + geo_id: geoIds[j], + annee_universitaire: years[i], + niveau_geo: data[0]?.niveau_geo, + geo_nom: data[0]?.geo_nom, + effectifPR: effectifPR, + effectifPU: effectifPU, + pctPR: pctPR, + pctPU: pctPU, + effectifF: effectifF, + effectifM: effectifM, + pctF: pctF, + pctM: pctM, + }; + + const result = await similarElementsCollection.insertOne(similarElement); + + // insert dans la collection board de la nouvelle version + const response = await db.collection("boards").updateOne( + { id: dashboardId, "data.id": collectionId }, + { + $push: { + "data.$.versions": { + id: newCollectionId, + createdAt: new Date().toISOString().split('T')[0], // yyyy-mm-dd + from: dependentCollectionId, + } + } + } + ); + }; + }; + } finally { + await db.close(); + res.status(200).json({ message: "Update done" }); + } +} + +await run({dependentCollectionId}).catch(console.dir); + + console.log('------------------------- fin ----------------------'); + +}); + export default router; diff --git a/server/src/routes/tableaux/atlas/api-tests/get-geo-ids-from-search.http b/server/src/routes/tableaux/atlas/api-tests/get-geo-ids-from-search.http new file mode 100644 index 00000000..4fb03f6c --- /dev/null +++ b/server/src/routes/tableaux/atlas/api-tests/get-geo-ids-from-search.http @@ -0,0 +1 @@ +GET http://localhost:3000/api/atlas/get-geo-ids-from-search?q=lyon \ No newline at end of file diff --git a/server/src/routes/tableaux/atlas/api-tests/get-indexes.http b/server/src/routes/tableaux/atlas/api-tests/get-indexes.http new file mode 100644 index 00000000..56daf802 --- /dev/null +++ b/server/src/routes/tableaux/atlas/api-tests/get-indexes.http @@ -0,0 +1 @@ +GET http://localhost:3000/api/atlas/get-indexes \ No newline at end of file diff --git a/server/src/routes/tableaux/atlas/index.js b/server/src/routes/tableaux/atlas/index.js index 44ee4651..8c04da1e 100644 --- a/server/src/routes/tableaux/atlas/index.js +++ b/server/src/routes/tableaux/atlas/index.js @@ -42,21 +42,42 @@ const filieresOrder = [ "TOTAL", ]; -const DEFAULT_CURRENT_YEAR = "2023-24"; -const START_YEAR = 2001; -const END_YEAR = 2023; +const getCurrentCollectionName = async (idCollection) => { + const data = await db.collection("boards").find({ id: "atlas" }).toArray(); + const currentCollection = data[0].data.find( + (item) => item.id === idCollection + ).current; + + if (currentCollection) { + return currentCollection; + } + if (idCollection === "atlas") { + return "atlas2024"; + } + if (idCollection === "similar-elements") { + return "similar-elements-2022-23"; + } +}; + +const getConstants = async () => { + const data = await db.collection("boards").find({ id: "atlas" }).toArray(); + return data[0].constants || []; +}; + +router.route("/atlas/get-geo-ids-from-search").get(async (req, res) => { + const currentCollectionName = await getCurrentCollectionName("atlas"); -router.route("/atlas/get-geo-ids-from-search").get((req, res) => { const normalizeString = (str) => { return str .toLowerCase() - .normalize('NFC') - .replace('é', 'e') - .replace('è', 'e') - .replace('à', 'a') - .replace('ç', 'c') - .replace(/-/g, ' '); - } + .normalize("NFC") + .replace("é", "e") + .replace("è", "e") + .replace("à", "a") + .replace("ç", "c") + .replace(/-/g, " "); + }; + if (!req.query.q || req.query?.q.length === 0) { res.status(400).send("the query is required"); } @@ -64,71 +85,70 @@ router.route("/atlas/get-geo-ids-from-search").get((req, res) => { const filters = {}; const searchQuery = normalizeString(req.query.q); filters.geo_nom = { $regex: searchQuery, $options: "i" }; - - db.collection("atlas2024") + + db.collection(currentCollectionName) .aggregate([ - { - $addFields: { - normalized_name: { - $toLower: { - $replaceAll: { - input: { - $replaceAll: { - input: { - $replaceAll: { - input: { - $replaceAll: { - input: { - $replaceAll: { - input: { - $toLower: { - $trim: { input: "$geo_nom" } - } - }, + { + $addFields: { + normalized_name: { + $toLower: { + $replaceAll: { + input: { + $replaceAll: { + input: { + $replaceAll: { + input: { + $replaceAll: { + input: { + $replaceAll: { + input: { + $toLower: { + $trim: { input: "$geo_nom" }, + }, + }, find: "é", - replacement: "e" - } - }, + replacement: "e", + }, + }, find: "è", - replacement: "e" - } - }, + replacement: "e", + }, + }, find: "à", - replacement: "a" - } + replacement: "a", + }, + }, + find: "-", + replacement: " ", }, - find: "-", - replacement: " " - } + }, + find: "ç", + replacement: "c", }, - find: "ç", - replacement: "c" - } - } - } - } - }, - { - $match: { - normalized_name: filters.geo_nom, - } - }, - { - $project: { - _id: 0, - geo_nom: 1, - geo_id: 1, - niveau_geo: 1, - normalized_name: 1 - } - }, - { - $sort: { geo_nom: 1 } - } - ]).toArray() + }, + }, + }, + }, + { + $match: { + normalized_name: filters.geo_nom, + }, + }, + { + $project: { + _id: 0, + geo_nom: 1, + geo_id: 1, + niveau_geo: 1, + normalized_name: 1, + }, + }, + { + $sort: { geo_nom: 1 }, + }, + ]) + .toArray() .then((response) => { - console.log("response", response); - const set = new Set(); const unique = []; response.map((item) => { @@ -178,7 +198,10 @@ router.route("/atlas/get-geo-polygons").get(async (req, res) => { filters.niveau_geo = "REGION"; } if (geoId.startsWith("R") || geoId.startsWith("A") || geoId.startsWith("P")) { - const ids = await db.collection("atlas2024").distinct("geo_id", filters); + const currentCollectionName = await getCurrentCollectionName("atlas"); + const ids = await db + .collection(currentCollectionName) + .distinct("geo_id", filters); if (geoId.startsWith("P") || geoId === "R00") { ids.push("D988"); //Nouvelle-Caledonie ids.push("D987"); //Polynesie-Francaise @@ -227,9 +250,10 @@ router.route("/atlas/get-geo-polygons").get(async (req, res) => { } }); -router.route("/atlas/number-of-students-map").get((req, res) => { +router.route("/atlas/number-of-students-map").get(async (req, res) => { + const currentCollectionName = await getCurrentCollectionName("atlas"); const allData = {}; - db.collection("atlas2024") + db.collection(currentCollectionName) .find(req.query, { projection: { effectif: 1, geo_id: 1 } }) .toArray() .then((data) => { @@ -266,14 +290,16 @@ router.route("/atlas/get-parents-from-geo-id").get(async (req, res) => { res.status(400).send("geo_id is required"); } + const currentCollectionName = await getCurrentCollectionName("atlas"); + const data = await db - .collection("atlas2024") + .collection(currentCollectionName) .aggregate([ { $match: { geo_id: geoId } }, { $limit: 1 }, { $lookup: { - from: "atlas2024", + from: currentCollectionName, localField: "aca_id", foreignField: "geo_id", as: "academie", @@ -293,7 +319,7 @@ router.route("/atlas/get-parents-from-geo-id").get(async (req, res) => { }, { $lookup: { - from: "atlas2024", + from: currentCollectionName, localField: "reg_id", foreignField: "geo_id", as: "region", @@ -314,7 +340,7 @@ router.route("/atlas/get-parents-from-geo-id").get(async (req, res) => { }, { $lookup: { - from: "atlas2024", + from: currentCollectionName, localField: "dep_id", foreignField: "geo_id", as: "departement", @@ -336,7 +362,7 @@ router.route("/atlas/get-parents-from-geo-id").get(async (req, res) => { }, { $lookup: { - from: "atlas2024", + from: currentCollectionName, localField: "uucr_id", foreignField: "geo_id", as: "uu", @@ -379,325 +405,368 @@ router.route("/atlas/get-parents-from-geo-id").get(async (req, res) => { }); }); -router.route("/atlas/number-of-students-historic-by-level").get(async (req, res) => { - const filters = { ...req.query }; - if (req.query.niveau_geo === "ACADEMIE") { - filters.niveau_geo = "REGION"; - } - if (req.query.niveau_geo === "DEPARTEMENT") { - filters.niveau_geo = "ACADEMIE"; - } - if (req.query.niveau_geo === "COMMUNE") { - filters.niveau_geo = "DEPARTEMENT"; - } +router + .route("/atlas/number-of-students-historic-by-level") + .get(async (req, res) => { + const filters = { ...req.query }; + if (req.query.niveau_geo === "ACADEMIE") { + filters.niveau_geo = "REGION"; + } + if (req.query.niveau_geo === "DEPARTEMENT") { + filters.niveau_geo = "ACADEMIE"; + } + if (req.query.niveau_geo === "COMMUNE") { + filters.niveau_geo = "DEPARTEMENT"; + } - const response = await db - .collection("atlas2024") - .findOne({ ...filters }, { projection: { geo_nom: 1 } }); - const levelName = response?.geo_nom || "France"; - - let query = req.query; - if ( - !req.query.geo_id && - !req.query.reg_id && - !req.query.dep_id && - !req.query.uucr_id && - !req.query.aca_id - ) { - // cas PAYS_100 - query = { - geo_id: { $ne: "R99" }, // français à l'etrangers - $or: [ - { geo_id: "D978" }, - { geo_id: "D986" }, - { geo_id: "D987" }, - { geo_id: "D988" }, - { niveau_geo: req.query.niveau_geo }, - ], - }; - } + const currentCollectionName = await getCurrentCollectionName("atlas"); + const response = await db + .collection(currentCollectionName) + .findOne({ ...filters }, { projection: { geo_nom: 1 } }); + const levelName = response?.geo_nom || "France"; + + let query = req.query; + if ( + !req.query.geo_id && + !req.query.reg_id && + !req.query.dep_id && + !req.query.uucr_id && + !req.query.aca_id + ) { + // cas PAYS_100 + query = { + geo_id: { $ne: "R99" }, // français à l'etrangers + $or: [ + { geo_id: "D978" }, + { geo_id: "D986" }, + { geo_id: "D987" }, + { geo_id: "D988" }, + { niveau_geo: req.query.niveau_geo }, + ], + }; + } - db.collection("atlas2024") - .find(query, { - projection: { - effectif: 1, - geo_id: 1, - geo_nom: 1, - annee_universitaire: 1, - regroupement: 1, - _id: 0, - }, - }) - .toArray() - .then((data) => { - const years = [ - ...new Set(data.map((item) => item.annee_universitaire)), - ].sort((a, b) => { - if (a > b) return 1; - if (a < b) return -1; - return 0; - }); + db.collection(currentCollectionName) + .find(query, { + projection: { + effectif: 1, + geo_id: 1, + geo_nom: 1, + annee_universitaire: 1, + regroupement: 1, + _id: 0, + }, + }) + .toArray() + .then((data) => { + const years = [ + ...new Set(data.map((item) => item.annee_universitaire)), + ].sort((a, b) => { + if (a > b) return 1; + if (a < b) return -1; + return 0; + }); - const geoIds = [...new Set(data.map((item) => item.geo_id))]; - const dataByGeo = []; - geoIds.map((geo_id) => { - dataByGeo.push({ - geo_id, // ex: "A24" - geo_nom: data.find((item) => item.geo_id === geo_id).geo_nom, // ex: "Créteil" - data: years.map((year) => { - return { - annee_universitaire: year, - effectif: data - .filter( - (item) => - item.annee_universitaire === year && - item.geo_id === geo_id && - item.regroupement === "TOTAL" - ) - ?.reduce((acc, item) => acc + item.effectif, 0), - }; - }), + const geoIds = [...new Set(data.map((item) => item.geo_id))]; + const dataByGeo = []; + geoIds.map((geo_id) => { + dataByGeo.push({ + geo_id, // ex: "A24" + geo_nom: data.find((item) => item.geo_id === geo_id).geo_nom, // ex: "Créteil" + data: years.map((year) => { + return { + annee_universitaire: year, + effectif: data + .filter( + (item) => + item.annee_universitaire === year && + item.geo_id === geo_id && + item.regroupement === "TOTAL" + ) + ?.reduce((acc, item) => acc + item.effectif, 0), + }; + }), + }); }); - }); - res.json({ - level_nom: levelName, // ex: "Ile-de-France" - data: dataByGeo, + res.json({ + level_nom: levelName, // ex: "Ile-de-France" + data: dataByGeo, + }); }); - }); -}); + }); -router.route("/atlas/number-of-students-by-gender-and-level").get(async (req, res) => { - const filters = { ...req.query }; - if (!req.query.annee_universitaire) { - filters.annee_universitaire = DEFAULT_CURRENT_YEAR; - } - const data = await db - .collection("atlas2024") - .aggregate([ - { $match: filters }, - { - $group: { - _id: { - genre: "$sexe", - regroupement: "$regroupement", - rgp_formations_ou_etablissements: - "$rgp_formations_ou_etablissements", +router + .route("/atlas/number-of-students-by-gender-and-level") + .get(async (req, res) => { + const filters = { ...req.query }; + const constants = await getConstants(); + const DEFAULT_CURRENT_YEAR = constants.find( + (el) => el.key === "DEFAULT_CURRENT_YEAR" + )?.value; + + if (!req.query.annee_universitaire) { + filters.annee_universitaire = DEFAULT_CURRENT_YEAR; + } + const currentCollectionName = await getCurrentCollectionName("atlas"); + const data = await db + .collection(currentCollectionName) + .aggregate([ + { $match: filters }, + { + $group: { + _id: { + genre: "$sexe", + regroupement: "$regroupement", + rgp_formations_ou_etablissements: + "$rgp_formations_ou_etablissements", + }, + effectif: { $sum: "$effectif" }, }, - effectif: { $sum: "$effectif" }, - }, - }, - { - $project: { - _id: 0, - genre: "$_id.genre", - regroupement: "$_id.regroupement", - effectif: 1, - label: "$_id.rgp_formations_ou_etablissements", }, - }, - { $sort: { regroupement: 1 } }, - { - $group: { - _id: { regroupement: "$regroupement" }, - effectif_masculin: { - $sum: { $cond: [{ $eq: ["$genre", "1"] }, "$effectif", 0] }, + { + $project: { + _id: 0, + genre: "$_id.genre", + regroupement: "$_id.regroupement", + effectif: 1, + label: "$_id.rgp_formations_ou_etablissements", }, - effectif_feminin: { - $sum: { $cond: [{ $eq: ["$genre", "2"] }, "$effectif", 0] }, + }, + { $sort: { regroupement: 1 } }, + { + $group: { + _id: { regroupement: "$regroupement" }, + effectif_masculin: { + $sum: { $cond: [{ $eq: ["$genre", "1"] }, "$effectif", 0] }, + }, + effectif_feminin: { + $sum: { $cond: [{ $eq: ["$genre", "2"] }, "$effectif", 0] }, + }, + effectif_total: { $sum: "$effectif" }, + label: { $first: "$label" }, }, - effectif_total: { $sum: "$effectif" }, - label: { $first: "$label" }, }, - }, - { - $project: { - _id: 0, - id: "$_id.regroupement", - effectif_masculin: 1, - effectif_feminin: 1, - effectif_total: 1, - label: 1, + { + $project: { + _id: 0, + id: "$_id.regroupement", + effectif_masculin: 1, + effectif_feminin: 1, + effectif_total: 1, + label: 1, + }, }, - }, - ]) - .toArray(); + ]) + .toArray(); - const ret = []; - filieresOrder.map((regroupementId) => { - const datRegroupement = data.find((item) => item.id === regroupementId); - if (datRegroupement) { - ret.push(datRegroupement); - } - }); + const ret = []; + filieresOrder.map((regroupementId) => { + const datRegroupement = data.find((item) => item.id === regroupementId); + if (datRegroupement) { + ret.push(datRegroupement); + } + }); - res.json(ret); -}); + res.json(ret); + }); -router.route("/atlas/number-of-students-by-sector-and-sublevel").get(async (req, res) => { - const filters = { ...req.query }; - if (!req.query.annee_universitaire) { - filters.annee_universitaire = DEFAULT_CURRENT_YEAR; - } - filters.regroupement = "TOTAL"; +router + .route("/atlas/number-of-students-by-sector-and-sublevel") + .get(async (req, res) => { + const filters = { ...req.query }; + const constants = await getConstants(); + const DEFAULT_CURRENT_YEAR = constants.find( + (el) => el.key === "DEFAULT_CURRENT_YEAR" + )?.value; + + if (!req.query.annee_universitaire) { + filters.annee_universitaire = DEFAULT_CURRENT_YEAR; + } + filters.regroupement = "TOTAL"; - const data = await db - .collection("atlas2024") - .aggregate([ - { $match: filters }, - { - $group: { - _id: { - geo_id: "$geo_id", - geo_nom: "$geo_nom", - secteur: "$secteur", + const currentCollectionName = await getCurrentCollectionName("atlas"); + + const data = await db + .collection(currentCollectionName) + .aggregate([ + { $match: filters }, + { + $group: { + _id: { + geo_id: "$geo_id", + geo_nom: "$geo_nom", + secteur: "$secteur", + }, + effectif: { $sum: "$effectif" }, }, - effectif: { $sum: "$effectif" }, - }, - }, - { - $project: { - _id: 0, - secteur: "$_id.secteur", - geo_id: "$_id.geo_id", - geo_nom: "$_id.geo_nom", - effectif: 1, }, - }, - { - $group: { - _id: { geo_id: "$geo_id", geo_nom: "$geo_nom" }, - effectif_secteur_public: { - $sum: { $cond: [{ $eq: ["$secteur", "PU"] }, "$effectif", 0] }, + { + $project: { + _id: 0, + secteur: "$_id.secteur", + geo_id: "$_id.geo_id", + geo_nom: "$_id.geo_nom", + effectif: 1, }, - effectif_secteur_prive: { - $sum: { $cond: [{ $eq: ["$secteur", "PR"] }, "$effectif", 0] }, + }, + { + $group: { + _id: { geo_id: "$geo_id", geo_nom: "$geo_nom" }, + effectif_secteur_public: { + $sum: { $cond: [{ $eq: ["$secteur", "PU"] }, "$effectif", 0] }, + }, + effectif_secteur_prive: { + $sum: { $cond: [{ $eq: ["$secteur", "PR"] }, "$effectif", 0] }, + }, + effectif_total: { $sum: "$effectif" }, }, - effectif_total: { $sum: "$effectif" }, }, - }, - { - $project: { - _id: 0, - id: "$_id.geo_id", - nom: "$_id.geo_nom", - effectif_secteur_public: 1, - effectif_secteur_prive: 1, - effectif_total: 1, + { + $project: { + _id: 0, + id: "$_id.geo_id", + nom: "$_id.geo_nom", + effectif_secteur_public: 1, + effectif_secteur_prive: 1, + effectif_total: 1, + }, }, - }, - { $sort: { effectif_total: -1 } }, - ]) - .toArray(); - res.json(data); -}); + { $sort: { effectif_total: -1 } }, + ]) + .toArray(); + res.json(data); + }); -router.route("/atlas/number-of-students-by-gender-and-sublevel").get(async (req, res) => { - const filters = { ...req.query }; - if (!req.query.annee_universitaire) { - filters.annee_universitaire = DEFAULT_CURRENT_YEAR; - } +router + .route("/atlas/number-of-students-by-gender-and-sublevel") + .get(async (req, res) => { + const filters = { ...req.query }; + const constants = await getConstants(); + const DEFAULT_CURRENT_YEAR = constants.find( + (el) => el.key === "DEFAULT_CURRENT_YEAR" + )?.value; + + if (!req.query.annee_universitaire) { + filters.annee_universitaire = DEFAULT_CURRENT_YEAR; + } - const data = await db - .collection("atlas2024") - .aggregate([ - { $match: filters }, - { - $group: { - _id: { - geo_id: "$geo_id", - geo_nom: "$geo_nom", - sexe: "$sexe", + const currentCollectionName = await getCurrentCollectionName("atlas"); + + const data = await db + .collection(currentCollectionName) + .aggregate([ + { $match: filters }, + { + $group: { + _id: { + geo_id: "$geo_id", + geo_nom: "$geo_nom", + sexe: "$sexe", + }, + effectif: { $sum: "$effectif" }, }, - effectif: { $sum: "$effectif" }, }, - }, - { - $project: { - _id: 0, - sexe: "$_id.sexe", - geo_id: "$_id.geo_id", - geo_nom: "$_id.geo_nom", - effectif: 1, - }, - }, - { - $group: { - _id: { geo_id: "$geo_id", geo_nom: "$geo_nom" }, - effectif_feminin: { - $sum: { $cond: [{ $eq: ["$sexe", "2"] }, "$effectif", 0] }, + { + $project: { + _id: 0, + sexe: "$_id.sexe", + geo_id: "$_id.geo_id", + geo_nom: "$_id.geo_nom", + effectif: 1, }, - effectif_masculin: { - $sum: { $cond: [{ $eq: ["$sexe", "1"] }, "$effectif", 0] }, + }, + { + $group: { + _id: { geo_id: "$geo_id", geo_nom: "$geo_nom" }, + effectif_feminin: { + $sum: { $cond: [{ $eq: ["$sexe", "2"] }, "$effectif", 0] }, + }, + effectif_masculin: { + $sum: { $cond: [{ $eq: ["$sexe", "1"] }, "$effectif", 0] }, + }, + effectif_total: { $sum: "$effectif" }, }, - effectif_total: { $sum: "$effectif" }, }, - }, - { - $project: { - _id: 0, - id: "$_id.geo_id", - nom: "$_id.geo_nom", - effectif_feminin: 1, - effectif_masculin: 1, - effectif_total: 1, + { + $project: { + _id: 0, + id: "$_id.geo_id", + nom: "$_id.geo_nom", + effectif_feminin: 1, + effectif_masculin: 1, + effectif_total: 1, + }, }, - }, - { $sort: { effectif_total: -1 } }, - ]) - .toArray(); - res.json(data); -}); + { $sort: { effectif_total: -1 } }, + ]) + .toArray(); + res.json(data); + }); -router.route("/atlas/number-of-students-by-field-and-sublevel").get(async (req, res) => { - const filters = { ...req.query }; - if (!req.query.annee_universitaire) { - filters.annee_universitaire = DEFAULT_CURRENT_YEAR; - } +router + .route("/atlas/number-of-students-by-field-and-sublevel") + .get(async (req, res) => { + const filters = { ...req.query }; + const constants = await getConstants(); + const DEFAULT_CURRENT_YEAR = constants.find( + (el) => el.key === "DEFAULT_CURRENT_YEAR" + )?.value; + + if (!req.query.annee_universitaire) { + filters.annee_universitaire = DEFAULT_CURRENT_YEAR; + } - const data = await db - .collection("atlas2024") - .aggregate([ - { $match: filters }, - { - $group: { - _id: { - geo_id: "$geo_id", - geo_nom: "$geo_nom", + const currentCollectionName = await getCurrentCollectionName("atlas"); + + const data = await db + .collection(currentCollectionName) + .aggregate([ + { $match: filters }, + { + $group: { + _id: { + geo_id: "$geo_id", + geo_nom: "$geo_nom", + }, + effectif: { $sum: "$effectif" }, }, - effectif: { $sum: "$effectif" }, }, - }, - { - $project: { - _id: 0, - geo_id: "$_id.geo_id", - geo_nom: "$_id.geo_nom", - effectif: 1, + { + $project: { + _id: 0, + geo_id: "$_id.geo_id", + geo_nom: "$_id.geo_nom", + effectif: 1, + }, }, - }, - { - $group: { - _id: { geo_id: "$geo_id", geo_nom: "$geo_nom" }, - effectif_total: { $sum: "$effectif" }, + { + $group: { + _id: { geo_id: "$geo_id", geo_nom: "$geo_nom" }, + effectif_total: { $sum: "$effectif" }, + }, }, - }, - { - $project: { - _id: 0, - id: "$_id.geo_id", - nom: "$_id.geo_nom", - effectif_total: 1, + { + $project: { + _id: 0, + id: "$_id.geo_id", + nom: "$_id.geo_nom", + effectif_total: 1, + }, }, - }, - { $sort: { effectif_total: -1 } }, - ]) - .toArray(); - res.json(data); -}); + { $sort: { effectif_total: -1 } }, + ]) + .toArray(); + res.json(data); + }); -router.route("/atlas/number-of-students").get((req, res) => { +router.route("/atlas/number-of-students").get(async (req, res) => { const filters = { ...req.query }; + const constants = await getConstants(); + const DEFAULT_CURRENT_YEAR = constants.find( + (el) => el.key === "DEFAULT_CURRENT_YEAR" + )?.value; + if (!req.query.annee_universitaire) { filters.annee_universitaire = DEFAULT_CURRENT_YEAR; } @@ -707,7 +776,10 @@ router.route("/atlas/number-of-students").get((req, res) => { } const allData = {}; - db.collection("atlas2024") + + const currentCollectionName = await getCurrentCollectionName("atlas"); + + db.collection(currentCollectionName) .find(filters) .toArray() .then( @@ -833,7 +905,7 @@ router.route("/atlas/number-of-students").get((req, res) => { ); }); -router.route("/atlas/number-of-students-by-year").get((req, res) => { +router.route("/atlas/number-of-students-by-year").get(async (req, res) => { const filters = {}; if (req.query.geo_id) { filters.geo_id = req.query.geo_id; @@ -845,7 +917,13 @@ router.route("/atlas/number-of-students-by-year").get((req, res) => { } else { filters.regroupement = "TOTAL"; } - db.collection("atlas2024") + + const currentCollectionName = await getCurrentCollectionName("atlas"); + const constants = await getConstants(); + const START_YEAR = constants.find((el) => el.key === "START_YEAR")?.value; + const END_YEAR = constants.find((el) => el.key === "END_YEAR")?.value; + + db.collection(currentCollectionName) .find(filters) .toArray() .then((data) => { @@ -888,15 +966,16 @@ router.route("/atlas/number-of-students-by-year").get((req, res) => { return 0; }); - // ajout des années manquantes (à zéro) const START_YEAR = "2001" => END_YEAR"; const range = []; - for (let year = START_YEAR; year <= END_YEAR; year++) { + for (let year = Number(START_YEAR); year <= Number(END_YEAR); year++) { range.push(year); } const dataByYearFull = []; for (let i = 0; i < range.length; i++) { - const currentYear = `${range[i]}-${(range[i] + 1).toString().slice(-2)}`; + const currentYear = `${range[i]}-${(range[i] + 1) + .toString() + .slice(-2)}`; if (!dataByYear.find((el) => el.annee_universitaire === currentYear)) { dataByYearFull.push({ annee_universitaire: currentYear, @@ -910,7 +989,9 @@ router.route("/atlas/number-of-students-by-year").get((req, res) => { effectif_ing: 0, }); } else { - dataByYearFull.push(dataByYear.find((el) => el.annee_universitaire === currentYear)); + dataByYearFull.push( + dataByYear.find((el) => el.annee_universitaire === currentYear) + ); } } @@ -918,16 +999,20 @@ router.route("/atlas/number-of-students-by-year").get((req, res) => { }); }); -router.route("/atlas/get-years").get((req, res) => { - db.collection("atlas2024") +router.route("/atlas/get-years").get(async (req, res) => { + const currentCollectionName = await getCurrentCollectionName("atlas"); + + db.collection(currentCollectionName) .distinct("annee_universitaire") .then((data) => { res.json(data); }); }); -router.route("/atlas/get-filieres").get((req, res) => { - db.collection("atlas2024") +router.route("/atlas/get-filieres").get(async (req, res) => { + const currentCollectionName = await getCurrentCollectionName("atlas"); + + db.collection(currentCollectionName) .distinct("regroupement") .then((data) => { res.json(data); @@ -940,14 +1025,16 @@ router.route("/atlas/get-filters-values").get(async (req, res) => { filters = { geo_id: req.query.geo_id }; } + const currentCollectionName = await getCurrentCollectionName("atlas"); + const annees_universitaires_onlyData = await db - .collection("atlas2024") + .collection(currentCollectionName) .distinct("annee_universitaire", filters); const annees_universitaires_all = await db - .collection("atlas2024") + .collection(currentCollectionName) .distinct("annee_universitaire"); const temp = await db - .collection("atlas2024") + .collection(currentCollectionName) .aggregate([ { $group: { @@ -990,7 +1077,11 @@ router.route("/atlas/get-filters-values").get(async (req, res) => { }); router.route("/atlas/get-references").get(async (req, res) => { - const response = await db.collection("atlas2024").findOne({ ...req.query }); + const currentCollectionName = await getCurrentCollectionName("atlas"); + + const response = await db + .collection(currentCollectionName) + .findOne({ ...req.query }); const { niveau_geo } = response; const objMapping = { @@ -1004,7 +1095,7 @@ router.route("/atlas/get-references").get(async (req, res) => { const obj = {}; obj.data = await db - .collection("atlas2024") + .collection(currentCollectionName) .aggregate([ { $match: { [objMapping[niveau_geo]]: req.query.geo_id } }, { @@ -1058,7 +1149,11 @@ router.route("/atlas/get-similar-elements").get(async (req, res) => { $lt: parseInt(req.query.lt), }; - db.collection("similar-elements") + const currentCollectionName = await getCurrentCollectionName( + "similar-elements" + ); + + db.collection(currentCollectionName) .find(filters) .toArray() .then((data) => { @@ -1066,4 +1161,13 @@ router.route("/atlas/get-similar-elements").get(async (req, res) => { }); }); +router.route("/atlas/get-indexes").get(async (req, res) => { + const currentCollectionName = await getCurrentCollectionName( + req.query.collectionId + ); + + const response = await db.collection(currentCollectionName).indexes(); + res.json(response); +}); + export default router;