/* * Welcome to your app's main JavaScript file! * * We recommend including the built version of this JavaScript file * (and its CSS file) in your base layout (base.html.twig). */ // any CSS you import will output into a single css file (app.css in this case) import './styles/app.css'; // start the Stimulus application // import './bootstrap'; import './utils.js'; import './opening_hours.js'; import './josm.js'; import './edit.js'; import Chart from 'chart.js/auto'; import ChartDataLabels from 'chartjs-plugin-datalabels'; import { genererCouleurPastel, setupCitySearch, handleAddCityFormSubmit, enableLabourageForm, getLabourerUrl, adjustListGroupFontSize } from './utils.js'; import Tablesort from 'tablesort'; window.Chart = Chart; window.genererCouleurPastel = genererCouleurPastel; window.setupCitySearch = setupCitySearch; window.handleAddCityFormSubmit = handleAddCityFormSubmit; window.getLabourerUrl = getLabourerUrl; Chart.register(ChartDataLabels); function initDashboardChart() { const chartCanvas = document.getElementById('statsBubbleChart'); if (!chartCanvas) { return; } if (!chartCanvas.dataset.stats || chartCanvas.dataset.stats.length <= 2) { // <= 2 pour ignorer '[]' console.log("Les données du graphique sont vides ou absentes, le graphique ne sera pas affiché."); return; } const statsData = JSON.parse(chartCanvas.dataset.stats); if (statsData && statsData.length > 0) { const bubbleChartData = statsData.map(stat => { const population = parseInt(stat.population, 10); const placesCount = parseInt(stat.placesCount, 10); const ratio = population > 0 ? (placesCount / population) * 1000 : 0; return { x: population, y: ratio, r: Math.sqrt(placesCount) * 2, label: stat.name, completion: stat.completionPercent || 0 }; }); new Chart(chartCanvas.getContext('2d'), { type: 'bubble', data: { datasets: [{ label: 'Villes', data: bubbleChartData, backgroundColor: bubbleChartData.map(d => `rgba(255, 99, 132, ${d.completion / 100})`), borderColor: 'rgba(255, 99, 132, 1)', }] }, options: { responsive: true, plugins: { datalabels: { anchor: 'center', align: 'center', color: '#000', font: { weight: 'bold' }, formatter: (value, context) => { return context.dataset.data[context.dataIndex].label; } }, legend: { display: false }, tooltip: { callbacks: { label: (context) => { const d = context.raw; return [ `${d.label}`, `Population: ${d.x.toLocaleString()}`, `Lieux / 1000 hab: ${d.y.toFixed(2)}`, `Total lieux: ${Math.round(Math.pow(d.r / 2, 2))}`, `Complétion: ${d.completion}%` ]; } } } }, scales: { x: { type: 'logarithmic', title: { display: true, text: 'Population (échelle log)' } }, y: { title: { display: true, text: 'Commerces pour 1000 habitants' } } } } }); } } // Attendre le chargement du DOM document.addEventListener('DOMContentLoaded', () => { console.log('DOMContentLoaded'); const randombg = genererCouleurPastel(); // Appliquer la couleur au body document.querySelectorAll('body, .edit-land, .body-landing').forEach(element => { element.style.backgroundColor = randombg; }); // Gestion du bouton pour afficher tous les champs const btnShowAllFields = document.querySelector('#showAllFields'); if (btnShowAllFields) { console.log('btnShowAllFields détecté'); btnShowAllFields.addEventListener('click', () => { // Sélectionner tous les inputs dans le formulaire const form = document.querySelector('form'); if (form) { // Sélectionner tous les inputs sauf #validation_messages const hiddenInputs = form.querySelectorAll('#advanced_tags'); hiddenInputs.forEach(input => { input.classList.toggle('d-none'); }); } }); } const btnClosedCommerce = document.querySelector('#closedCommerce'); if (btnClosedCommerce) { btnClosedCommerce.addEventListener('click', () => { if (!confirm('Êtes-vous sûr de vouloir signaler ce commerce comme fermé ?')) { return; } window.location.href = '/closed_commerce/' + document.getElementById('app_public_closed_commerce').value; }); } openingHoursFormManager.init(); // Vérifier si l'élément avec l'ID 'userChangesHistory' existe avant d'appeler la fonction if (document.getElementById('userChangesHistory')) { listChangesets(); } else { console.log('userChangesHistory non trouvé'); } document.querySelectorAll('input[type="text"]').forEach(input => { input.addEventListener('blur', updateCompletionProgress); }); const form = document.querySelector('form') if (form) { form.addEventListener('submit', check_validity); updateCompletionProgress() } updateCompletionProgress(); // Activer le tri sur tous les tableaux désignés document.querySelectorAll('.js-sort-table').forEach(table => { new Tablesort(table); }); // Focus sur le premier champ texte au chargement const firstTextInput = document.querySelector('input.form-control'); if (firstTextInput) { firstTextInput.focus(); console.log('focus sur le premier champ texte', firstTextInput); } else { console.log('pas de champ texte trouvé'); } parseCuisine(); // Tri automatique des tableaux // const tables = document.querySelectorAll('table'); // tables.forEach(table => { // table.classList.add('js-sort-table'); // }); // Modifier la fonction de recherche existante const searchInput = document.getElementById('app_admin_labourer'); const suggestionList = document.getElementById('suggestionList'); if (searchInput && suggestionList) { let timeoutId; searchInput.addEventListener('input', () => { clearTimeout(timeoutId); const query = searchInput.value.trim(); if (query.length < 2) { suggestionList.innerHTML = ''; return; } timeoutId = setTimeout(async () => { const suggestions = await searchInseeCode(query); suggestionList.innerHTML = ''; if (suggestions.length === 0) { const li = document.createElement('li'); li.style.cssText = ` padding: 8px 12px; color: #666; font-style: italic; `; li.textContent = 'Aucun résultat trouvé'; suggestionList.appendChild(li); return; } suggestions.forEach(suggestion => { const li = document.createElement('li'); li.style.cssText = ` padding: 8px 12px; cursor: pointer; border-bottom: 1px solid #eee; `; li.textContent = suggestion.label; li.addEventListener('mouseenter', () => { li.style.backgroundColor = '#f0f0f0'; }); li.addEventListener('mouseleave', () => { li.style.backgroundColor = 'white'; }); li.addEventListener('click', () => { searchInput.value = suggestion.insee; suggestionList.innerHTML = ''; labourer(); }); suggestionList.appendChild(li); }); }, 300); }); } enableLabourageForm(); initDashboardChart(); adjustListGroupFontSize('.list-group-item'); });