document.addEventListener("DOMContentLoaded", async function () { // Fetch data from the server //// parse TOken const token = localStorage.getItem("jwtToken"); if (!token) { throw new Error("Aucun token trouvé dans le localStorage."); } const userData = parseJwt(token); if (!userData) { displayError("Erreur lors de l'extraction des données utilisateur à partir du token."); return; } const { userAuthGroupe, userMatricule } = userData; const isAdmin = userAuthGroupe === "ADMIN"; const matriculeUser = userMatricule; let regionUser; let tableData = []; const checkAdmin = document.querySelector('#checkRegionAdmin'); if (isAdmin) { checkAdmin.style.display = "flex"; } try { const userResponse = await fetchUserDetails(matriculeUser); regionUser = userResponse?.user["@expand"].region?.nom || null; } catch (error) { displayError("Erreur lors de la récupération des données utilisateur."); return; } const checkboxWrappers = Array.from(document.querySelectorAll('[class^="checkbox-wrapper-"]')); const checkboxes = checkboxWrappers.map(wrapper => wrapper.querySelector('input[type="checkbox"]')); const regions = checkboxWrappers.map(wrapper => wrapper.querySelector('.checkboxRegion').textContent); // Initialize checkboxes checkboxes.forEach((checkbox, index) => { if (regions[index] === regionUser) { checkbox.checked = true; } }); // Fetch initial data try { const response = await fetch(`/historiqueParcours/${regionUser}`); const dataResponse = await response.json(); if (dataResponse.valid) { tableData = dataResponse.data; populateParcoursTable(tableData); } else { displayError("Erreur lors de la récupération des parcours"); } } catch (error) { displayError("Failed to fetch data. Please try again later."); } // Add event listeners to checkboxes checkboxes.forEach((checkbox, index) => { checkbox.addEventListener('change', async (e) => { const region = regions[index]; if (checkbox.checked) { try { const response = await fetch(`/historiqueParcours/${region}`); const dataResponse = await response.json(); if (dataResponse.valid) { tableData.push(...dataResponse.data); populateParcoursTable(tableData); } else { displayError("Erreur lors de la récupération des parcours"); } } catch (error) { displayError("Failed to fetch data. Please try again later."); } } else { removeRegionFromTableData(region); populateParcoursTable(tableData); } }); }); const removeRegionFromTableData = (region) => { tableData = tableData.filter(item => item["@expand"]?.dernierUtilisateur?.["@expand"]?.region?.nom !== (region === regionUser ? regionUser : region)); }; }); const removeRegionFromTableData = (region) => { if (region === regionUser) { tableData = tableData.filter(item => item["@expand"]?.dernierUtilisateur?.["@expand"]?.region?.nom !== regionUser); } else { tableData = tableData.filter(item => item["@expand"]?.dernierUtilisateur?.["@expand"]?.region?.nom !== region); } }; async function fetchUserDetails(matriculeUser) { try { const response = await fetch(`/user/read/matricule/${matriculeUser}`); const data = await response.json(); return data.valid ? data : null; } catch (error) { displayError(`Erreur lors de la récupération du contrat avec le matricule ${matriculeUser} :`, error); return null; } } function populateParcoursTable(parcoursData) { //initialise const table = $("#historiqueParcours").DataTable({ searching: true, paging: true, orderCellsTop: true, fixedHeader: true, responsive: true, pageLength: 5, retrieve: true, columnDefs: [ { type: "date-uk", targets: 10 }, { type: "date-eu", targets: 4 }, ], order: [[0, "desc"]], language: { search: "Rechercher", lengthMenu: "Afficher _MENU_ entrées par page", info: "Affichage de _START_ à _END_ sur _TOTAL_ entrées", infoEmpty: "Affichage de 0 à 0 sur 0 entrée", infoFiltered: "(filtré de _MAX_ entrées au total)", paginate: { first: "Début", previous: "Précédent", next: "Suivant", last: "Fin", }, }, initComplete: function () { const table = this.api(); $("#historiqueParcours thead tr:eq(1) th").each(function (i) { $("input", this).on("keyup change", function () { if (table.column(i).search() !== this.value) { table.column(i).search(this.value).draw(); } }); }); table.on("responsive-resize", function (e, datatable, columns) { // Loop over each column to see if it's visible for (let i = 0; i < columns.length; i++) { if (columns[i]) { $(table.column(i).header()).show(); $(table.column(i).footer()).show(); $($("#historiqueParcours thead tr:eq(1) th")[i]).show(); } else { $(table.column(i).header()).hide(); $(table.column(i).footer()).hide(); $($("#historiqueParcours thead tr:eq(1) th")[i]).hide(); } } }); $("#divToggleSearch").on("click", function () { $("#historiqueParcours thead tr:eq(1)").toggle(); }); $("#historiqueParcours thead tr:eq(1)").hide(); }, }); //clear existing data table.clear(); let row = null; let tableRow = null; //generate Project //loop on parcours parcoursData.forEach((parcours) => { const contratId = parcours["@expand"]?.contrat?.id; const contrat = contratId ? parcours["@expand"].contrat : null; const client = contrat ? contrat.client : null; const lastUser = parcours["@expand"]?.dernierUtilisateur; const region = lastUser["@expand"]?.region; const produit = contrat ? (contrat.produit ? contrat.produit : "NC") : "NC" row = [ parcours.numParcours, new Date(parcours.created).toLocaleDateString("fr-FR", { day: "numeric", month: "numeric", year: "numeric" }), parcours["@expand"].dernierUtilisateur?.matricule || "NC", parcours["@expand"].dernierUtilisateur ? `${parcours["@expand"].dernierUtilisateur.prenom} ${parcours["@expand"].dernierUtilisateur.nom}` : "NC", region ? region.nom : "NC", contrat ? (contrat.numSaisine ? contrat.numSaisine : "NC") : "NC", contrat ? (contrat.numContrat ? contrat.numContrat : "NC") : "NC", contrat ? (contrat.produit ? contrat.produit : "NC") : "NC", contrat ? (contrat.type ? contrat.type : "NC") : "NC", contrat ? contrat["@expand"]?.intermediaire?.numPortefeuille || "NC" : "NC", contrat ? contrat["@expand"]?.intermediaire?.nom || "NC" : "NC", client ? client.numClient || "NC" : "NC", client ? client.nom || "NC" : "NC", ``, ``, ]; tableRow = table.row.add(row).node(); // add class NC to style "Non communiqué" $(tableRow) .find("td") .each(function (colIndex) { if ($(this).text() === "NC") { $(this).addClass("nc-value"); } }); }); table.draw(); // for "afficher" entrées par page $("#historiqueParcours_length select").val("10").trigger("change"); } function downloadExcel(applyFilters) { const table = $("#historiqueParcours").DataTable(); // Get the DataTable instance const headers = $("#historiqueParcours th").filter(function () { return !$(this).hasClass("no-export");}).map(function () { return $(this).text().trim(); }).get(); const data = []; const rowsData = applyFilters ? table.rows({ filter: "applied" }).data() : table.rows().data(); rowsData.each(function (row) { const filteredRow = $(row).filter(function (index) { return !$("#historiqueParcours th").eq(index).hasClass("no-export"); }); data.push(filteredRow.get()); }); const ws = XLSX.utils.aoa_to_sheet([headers, ...data]); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Historique Parcours"); const wbout = XLSX.write(wb, { bookType: "xlsx", type: "binary" }); function s2ab(s) { const buf = new ArrayBuffer(s.length); const view = new Uint8Array(buf); for (let i = 0; i < s.length; i++) view[i] = s.charCodeAt(i) & 0xff; return buf; } const now = new Date(); const pad = (num) => String(num).padStart(2, "0"); const formattedDate = `${pad(now.getDate())}${pad(now.getMonth() + 1)}${now.getFullYear()}${pad(now.getHours())}${pad(now.getMinutes())}`; const blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" }); const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = `historique_parcours_${formattedDate}.xlsx`; document.body.appendChild(link); link.click(); document.body.removeChild(link); } function downloadCSV(applyFilters) { const table = $("#historiqueParcours").DataTable(); const headers = $("#historiqueParcours th").filter(function () { return !$(this).hasClass("no-export");}).map(function () { return $(this).text().trim(); }).get(); let csvContent = "data:text/csv;charset=utf-8," + headers.join(";") + "\n"; const rowsData = applyFilters ? table.rows({ filter: "applied" }).data() : table.rows().data(); rowsData.each(function (row) { let filteredRow = row.filter((cell, index) => { return !$(`#historiqueParcours th`).eq(index).hasClass("no-export"); }); csvContent += filteredRow.join(";") + "\n"; }); const encodedUri = encodeURI(csvContent); const link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", "historique_parcours.csv"); document.body.appendChild(link); link.click(); } async function generateProject(numParcours, produit) { try { const response = await fetch(`/generate/${produit}/projet/${numParcours}`, { method: "POST", headers: { "Content-Type": "application/json"}, }); if (!response.ok) throw new Error("Erreur réseau ou serveur"); const disposition = response.headers.get("content-disposition"); const filename = disposition.split(";")[1].trim().split("=")[1]; const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); a.remove(); } catch (error) { console.error("Erreur lors de la génération du projet:", error); } } // Fonction pour décoder le JWT function parseJwt(token) { try { const base64Url = token.split(".")[1]; const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/"); const jsonPayload = decodeURIComponent(atob(base64).split("").map(function (c) { return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);}).join("")); return JSON.parse(jsonPayload); } catch (error) { console.error("Erreur lors du décodage du token:", error); return null; } } //generagte Project $("#historiqueParcours").on("click", "button#btnGenerate", function() { const numParcours = $(this).data("num-parcours"); const produit = $(this).data("produit"); generateProject(numParcours, produit); }); //export CSV $("#exportCSV").on("click", function () { downloadCSV(false); }); //export CSV with filter $("#exportCSVFilter").on("click", function () { downloadCSV(true); }); //export to excel $("#exportXlxs").on("click", function () { downloadExcel(false); }); // export to excel using Filter $("#exportXlxsFilter").on("click", function () { downloadExcel(true); }); function displayError(message) { const errorElement = document.getElementById("error"); errorElement.textContent = message; errorElement.style.display = "block"; }