let myChart; document.addEventListener("DOMContentLoaded", async () => { const urlParams = new URLSearchParams(window.location.search); const projectId = urlParams.get("id"); const data = await getAllProject(); let DataMetrics; try { DataMetrics = await getDataMetrics(projectId); } catch (error) { if (error.status !== 404) { console.error(error); } DataMetrics = 404; // Assign a fallback value } const start_timelapse_button = document.getElementById("start-timelapse"); const videoSelector = document.getElementById("video_selector"); const numberPicker = document.getElementById("number-picker"); const choiceSelect = document.getElementById("choice"); const oneByOneContainer = document.getElementById("one-by-one-container"); const firstLastContainer = document.getElementById("first-last-container"); const addNumberButton = document.getElementById("add-number-button"); const formContainerProject = document.getElementById( "form-container-project" ); const formContainerCamera = document.getElementById("form-container-camera"); const durationInput = document.getElementById("duration"); const tableImage = document.getElementById("content1"); const numberBoard = document.getElementById("number-board"); // Add event listeners for the "Début" and "Fin" input fields const firstInput = document.getElementById("first"); const lastInput = document.getElementById("last"); const formContainerUpload = document.getElementById("form-container-upload"); const showFormButtonUpload = document.getElementById("show-form-button-upload"); const closeFormButtonUpload = document.getElementById("close-form-button-upload"); const manualUploadForm = document.getElementById("manual-upload-form"); if (formContainerUpload && showFormButtonUpload && closeFormButtonUpload && manualUploadForm) { showFormButtonUpload.addEventListener("click", () => { formContainerUpload.style.display = "flex"; }); closeFormButtonUpload.addEventListener("click", () => { formContainerUpload.style.display = "none"; }); manualUploadForm.addEventListener("submit", async (event) => { event.preventDefault(); const imageFile = document.getElementById("imageFile").files[0]; const temperature = document.getElementById("temperature").value; const humidity = document.getElementById("humidity").value; const timestamp = new Date().toISOString(); try { await manualUpload(imageFile, projectId, timestamp, temperature, humidity); alert("Image uploadée avec succès !"); formContainerUpload.style.display = "none"; } catch (error) { alert("Erreur lors de l'upload de l'image : " + error); } }); } else { console.error("Un ou plusieurs éléments du formulaire d'upload manuel sont introuvables."); } let selectedNumbers = []; populateTimelapseLogic(start_timelapse_button, projectId).then(() => { if (document.getElementById("show-form-button-project") != null) { document .getElementById("show-form-button-project") .addEventListener("click", showFormCamera); document .getElementById("close-form-button-camera") .addEventListener("click", hideFormCamera); } if (document.getElementById("commencer") != null) { document .getElementById("commencer") .addEventListener("click", async () => { const days = document.getElementById("days").value; const hours = document.getElementById("hours").value; const minutes = document.getElementById("minutes").value; const frequency = days * 1440 + hours * 60 + minutes; if(frequency >= 3) { const nbrimages = document.getElementById("totalImages").value; try { // Attendre que la requête API soit terminée avant de recharger la page await start_timelapse(projectId, frequency, nbrimages); location.reload(); } catch (error) { console.error("Erreur lors du démarrage du timelapse:", error); } } else { alert("La fréquence doit être supérieure à 3 minutes !"); } }); } if (document.getElementById("stop-camera") != null) { document .getElementById("stop-camera") .addEventListener("click", async () => { try { // Attendre que la requête API soit terminée avant de recharger la page await stopCamera(projectId); location.reload(); } catch (error) { console.error("Erreur lors de l'arrêt de la caméra:", error); } }); } }); if (addNumberButton) { addNumberButton.addEventListener("click", addSelectedNumber); } videoSelector.addEventListener("change", () => generateViewMetric(projectId) ); document .getElementById("show-form-button-camera") .addEventListener("click", showFormProject); document .getElementById("close-form-button-project") .addEventListener("click", hideFormProject); document .getElementById("increment-button") .addEventListener("click", incrementDuration); document .getElementById("decrement-button") .addEventListener("click", decrementDuration); document .getElementById("submit") .addEventListener("click", handleFormSubmit); document .getElementById("projets") .addEventListener("click", navigateToProjects); document .getElementById("toggle-view") .addEventListener("click", toggleView); firstInput.addEventListener("input", updateRange); lastInput.addEventListener("input", updateRange); function toggleContainers() { if (choiceSelect.value === "oneByOne") { oneByOneContainer.style.display = "block"; firstLastContainer.style.display = "none"; populateNumberBoard(DataMetrics.length); setRequiredAttributes(); } else { oneByOneContainer.style.display = "none"; firstLastContainer.style.display = "block"; const last = document.getElementById("last"); last.value = DataMetrics.length; last.max = DataMetrics.length; document.getElementById("first").max = last.value; setRequiredAttributes(); } } toggleContainers(); function setRequiredAttributes() { const firstInput = document.getElementById("first"); const lastInput = document.getElementById("last"); const denominatorInput = document.getElementById("denominator"); if (firstLastContainer.style.display === "block") { firstInput.required = true; lastInput.required = true; denominatorInput.required = true; } else { firstInput.required = false; lastInput.required = false; denominatorInput.required = false; } } function addSelectedNumber() { const selectedNumber = parseInt(numberPicker.value, 10); if (!selectedNumbers.includes(selectedNumber)) { selectedNumbers.push(selectedNumber); numberPicker.remove(numberPicker.selectedIndex); } } function showFormCamera() { formContainerCamera.style.display = "flex"; } function hideFormCamera() { formContainerCamera.style.display = "none"; } function showFormProject() { formContainerProject.style.display = "flex"; } function hideFormProject() { formContainerProject.style.display = "none"; } function incrementDuration() { durationInput.value = parseInt(durationInput.value) + 1; } function decrementDuration() { if (parseInt(durationInput.value) > 0) { durationInput.value = parseInt(durationInput.value) - 1; } } async function handleFormSubmit(event) { event.preventDefault(); const data = await getDataProjectVideosFromApi(projectId); const nameVideo = document.getElementById("name").value; const videoDuration = durationInput.value; const videoResolution = document.getElementById("resolution").value; if (videoDuration <= 0) { alert("La durée de la vidéo doit être supérieur à 0"); return 0; } if (!checkVideoPath(data, nameVideo) || !nameVideo.length > 0) { alert( 'Le nom : " ' + nameVideo + ' " est déjà pris ou vide ! \n' + "veuillez en trouver un autre" ); return 0; } const choice = choiceSelect.value; const measurementIds = getMeasurementsIdsFromForm( choice, firstInput, lastInput ); postNewVideo( projectId, measurementIds, nameVideo, videoResolution, videoDuration ).then(() => { alert( "Nouvelle vidéo enregistrée :\nNom : " + nameVideo + "\nRésolution : " + videoResolution + "\nDurée : " + videoDuration + " secondes" ); }); } function navigateToProjects() { window.location.href = "../index.html"; } function toggleView() { if (tableImage.classList.contains("hiddenTable")) { tableImage.classList.remove("hiddenTable"); tableImage.classList.add("full-view"); } else { tableImage.classList.remove("full-view"); tableImage.classList.add("hiddenTable"); } } function populateNumberBoard(length) { numberBoard.innerHTML = ""; numberBoard.style.gridTemplateColumns = `repeat(auto-fill, minmax(50px, 1fr))`; for (let i = 1; i <= length; i++) { const numberButton = document.createElement("button"); numberButton.classList.add("number-button"); numberButton.textContent = i; numberButton.addEventListener("click", () => highlightNumber(numberButton) ); numberBoard.appendChild(numberButton); } } function highlightNumber(button) { button.classList.toggle("highlight"); } function updateRange() { const firstValue = parseInt(firstInput.value); const lastValue = parseInt(lastInput.value); if (firstValue > lastValue) { lastInput.value = firstValue; } if (lastValue < firstValue) { firstInput.value = lastValue; } firstInput.max = lastValue; lastInput.min = firstValue; } const project = data.find((project) => project.id == projectId); if (project) { for (obj of document.getElementsByClassName("name_project")) obj.innerHTML = project.name; } else { console.error("Project not found"); } if (DataMetrics != 404) { choiceSelect.addEventListener("change", toggleContainers); generateViewMetric(projectId); PopulateSelect(videoSelector, projectId); } else { document.getElementById("metric_viewer").style.display = "none"; document.getElementById("video-container").style.display = "none"; document.getElementById("delete-placeholder").style.display = "none"; document.getElementById("content1").style.display = "none"; document.getElementById("form-container-project").style.display = "none"; document.getElementById("form-container-camera").style.display = "none"; document.getElementById("show-form-button-camera").style.display = "none"; for (el of document.querySelectorAll(".box")) { el.style.display = "none"; } document.getElementById("buttons-container").classList.add("middle-place"); document.getElementById("toggle-view").style.display = "none"; // add an explaination to the user const explaination = document.createElement("p"); explaination.innerHTML = "Ce projet est encore vierge, il n'y a pas de données à afficher.
Veuillez configurer la caméra pour commencer à prendre des images."; explaination.classList.add("explaination-text"); document.getElementById("title-global").appendChild(explaination); } }); function populateImageTable(DataMetrics) { const tableBody = document.getElementById("imageSource"); while (tableBody.rows.length > 0) { tableBody.deleteRow(0); } let row = document.createElement("tr"); let i = 0; DataMetrics.forEach((measure) => { let imageTD = document.createElement("td"); imageTD.innerHTML = ``; row.appendChild(imageTD); if ((i + 1) % 3 === 0 && i !== 0) { tableBody.appendChild(row); row = document.createElement("tr"); } if (row.childNodes.length > 0) { tableBody.appendChild(row); } i++; }); } async function generateViewMetric(projectId) { const ctx = document.getElementById("metric_viewer").getContext("2d"); const videoPlaceHolder = document.getElementById("video-container"); const deletePlaceHolder = document.getElementById("delete-placeholder"); let Hygrometrie = []; let Temperature = []; let datesMeasurement = []; let measurements; let currentVideoDatas; await new Promise((resolve) => { const checkExist = setInterval(() => { if (document.getElementById("video_selector").options.length > 0) { clearInterval(checkExist); resolve(); } }, 100); // check every 100ms }); const videoId = document.getElementById("video_selector").value; measurements = await getDataMetrics(projectId); if (measurements != 404) { let samples; if (videoId != -1) { try { console.log("videoId", videoId); currentVideoDatas = await getDataVideoFromApi(videoId); console.log("currentVideoDatas", currentVideoDatas); // Vérifier que currentVideoDatas existe et contient au moins un élément if (currentVideoDatas) { samples = JSON.parse(currentVideoDatas["measurement_ids"]); if (currentVideoDatas.status != 0) { videoPlaceHolder.innerHTML = ` `; } else { videoPlaceHolder.innerHTML = `

La vidéo n'a pas été rendered

`; } deletePlaceHolder.innerHTML = ` `; document.getElementById("delete-video").addEventListener("click", () => { showConfirmationAlert(videoId); }); tempoMeasure = filterAndSortMeasurementsByNumber(measurements, samples); } else { // Si aucune donnée n'est disponible pour cette vidéo console.warn("Aucune donnée disponible pour la vidéo sélectionnée"); deletePlaceHolder.innerHTML = ""; videoPlaceHolder.innerHTML = `

Données de vidéo non disponibles

`; samples = measurements.map((measurement) => measurement.id); tempoMeasure = filterAndSortMeasurementsByIds(measurements, samples); } } catch (error) { console.error("Erreur lors de la récupération des données vidéo:", error); deletePlaceHolder.innerHTML = ""; videoPlaceHolder.innerHTML = `

Erreur lors de la récupération des données vidéo

`; samples = measurements.map((measurement) => measurement.id); tempoMeasure = filterAndSortMeasurementsByIds(measurements, samples); } } else { deletePlaceHolder.innerHTML = ""; videoPlaceHolder.innerHTML = ""; samples = measurements.map((measurements) => measurements.id); tempoMeasure = filterAndSortMeasurementsByIds(measurements, samples); } tempoMeasure.forEach((measure) => { datesMeasurement.push(measure.timestamp); Temperature.push(measure.temperature); Hygrometrie.push(measure.humidity); }); populateImageTable(tempoMeasure); if (myChart) { myChart.destroy(); } myChart = new Chart(ctx, { type: "line", data: { labels: datesMeasurement, datasets: [ { label: "Température (C°)", data: Temperature, fill: false, borderColor: "rgba(75, 192, 192, 1)", tension: 0.1, yAxisID: "y", // Use the default y-axis }, { label: "Hygrometrie (%)", data: Hygrometrie, fill: false, color: "rgba(153, 102, 255, 1)", borderColor: "rgba(153, 102, 255, 1)", tension: 0.1, yAxisID: "y1", // Use the second y-axis }, ], }, options: { scales: { y: { beginAtZero: true, position: "left", ticks: { color: "white", // Set y-axis labels to white }, grid: { color: "white", // Set grid line color to white }, }, x: { ticks: { color: "white", // Set x-axis labels to white }, grid: { drawOnChartArea: true, color: "white", // Set grid line color to white }, }, y1: { beginAtZero: true, position: "right", grid: { drawOnChartArea: false, // Only want the grid lines for one axis to show up }, ticks: { color: "white", // Set y-axis labels to white }, }, }, plugins: { legend: { labels: { color: "white", // Set legend labels to white }, }, }, }, }); } else { document.getElementById("metric_viewer").style.display = "none"; } } function showConfirmationAlert(videoId) { const customAlert = document.getElementById("customAlert"); const alertMessage = document.getElementById("alertMessage"); const okBtn = document.getElementById("okBtn"); const cancelBtn = document.getElementById("cancelBtn"); alertMessage.textContent = "Are you sure you want to delete this video?"; customAlert.style.display = "block"; okBtn.onclick = function () { deleteVideo(videoId); customAlert.style.display = "none"; }; cancelBtn.onclick = function () { customAlert.style.display = "none"; }; } function convertStringToArray(string) { const numberStrings = string.replace(/[{}]/g, "").split(","); // Trim whitespace and convert the string numbers to integers const numberArray = numberStrings.map((num) => parseInt(num.trim(), 10)); return numberArray; } function filterAndSortMeasurementsByIds(measurements, ids) { return measurements .filter((measurement) => ids.includes(measurement.id)) .sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp)); } function filterAndSortMeasurementsByNumber(measurements, Numbers) { // Filter measurements based on their position in the Numbers array const filteredMeasurements = Numbers.map( (index) => measurements[index - 1] ).filter((measurement) => measurement !== undefined); // Sort the filtered measurements by their timestamp return filteredMeasurements.sort( (a, b) => new Date(a.timestamp) - new Date(b.timestamp) ); } function checkVideoPath(videos, name) { let res = true; // Vérifier si videos est un tableau et s'il a une méthode forEach if (videos && Array.isArray(videos) && videos.length > 0) { videos.forEach((video) => { const videoName = video.name; if (videoName == name) res = false; }); } else { // Si videos n'est pas un tableau valide, on considère qu'aucune vidéo n'existe // et donc n'importe quel nom est valide console.log("Aucune vidéo existante détectée"); } return res; } function getMeasurementsIdsFromForm(choice, firstInput, lastInput) { if (choice === "oneByOne") { const highlightedButtons = document.querySelectorAll( ".number-button.highlight" ); return Array.from(highlightedButtons).map((button) => parseInt(button.textContent) ); } else { const first = parseInt(firstInput.value); const last = parseInt(lastInput.value); const denominator = parseInt(document.getElementById("denominator").value); const measurementIds = new Set(); measurementIds.add(first); // Always include the first image // Iterate through the range, adding the step size for (let i = first + denominator; i <= last; i += denominator) { measurementIds.add(i); } measurementIds.add(last); // Always include the last image // Convert the Set back to an array and sort it return Array.from(measurementIds).sort((a, b) => a - b); } } async function populateTimelapseLogic(placeholder, id) { const data = await getSingleProject(id); if (data.status == 0) { placeholder.innerHTML = ``; } else if (data.status == 1) { placeholder.innerHTML = ``; } else if (data.status == 2) { // Ajout de la possibilité de configurer la caméra pour un projet avec statut "terminé" placeholder.innerHTML = ``; } else if (data.status == 3) { // Affichage d'un message pour indiquer que l'arrêt est en cours placeholder.innerHTML = ``; } else { placeholder.innerHTML = ``; } } function increment(id) { const input = document.getElementById(id); input.value = parseInt(input.value) + 1; updateFrequencyText(); } function decrement(id) { const input = document.getElementById(id); if (parseInt(input.value) > 0) { input.value = parseInt(input.value) - 1; } updateFrequencyText(); } function decrementImage(id) { const input = document.getElementById(id); if (parseInt(input.value) > 1) { input.value = parseInt(input.value) - 1; } updateFrequencyText(); } function updateFrequencyText() { const days = document.getElementById("days").value; const hours = document.getElementById("hours").value; const minutes = document.getElementById("minutes").value; const frequencyText = `une image sera prise toutes les ${days} jours ${hours} heures ${minutes} minutes`; document.getElementById("frequency-text").innerHTML = frequencyText; } $(".arrow-icon").click(function () { $(this).toggleClass("open"); }); let titleIsReadable = true; function change_title_style() { const xyz = document.getElementById("xyzv"); const h3_title = document.getElementById("h3-title"); if (titleIsReadable) { titleIsReadable = false; xyz.style.display = "block"; h3_title.style.display = "none"; } else { titleIsReadable = true; xyz.style.display = "none"; h3_title.style.display = "block"; } } change_title_style();