import {Controller} from '@hotwired/stimulus'; import { Modal } from "bootstrap"; import {TabulatorFull as Tabulator} from 'tabulator-tables'; import {eyeIconLink, pencilIcon, TABULATOR_FR_LANG, trashIcon} from "../js/global.js"; import base_controller from "./base_controller.js"; export default class extends base_controller { static values = { listProject : Boolean, orgId: Number, admin: Boolean } static targets = ["modal", "appList", "nameInput", "formTitle"]; connect(){ if(this.listProjectValue){ this.table(); } this.modal = new Modal(this.modalTarget); } table(){ const columns = [ {title: "ID ", field: "id", visible: false}, {title: "Nom du projet ", field: "name", headerFilter: "input", widthGrow: 2, vertAlign: "middle"}, { title: "Applications", field: "applications", headerSort: false, hozAlign: "left", formatter: (cell) => { const apps = cell.getValue(); if (!apps || apps.length === 0) { return "Aucune"; } // Wrap everything in a flex container to keep them on one line const content = apps.map(app => `
${app.name}
`).join(''); return `
${content}
`; } } ]; // 2. Add the conditional column if admin value is true if (this.adminValue) { columns.push({ title: "Base de données", field: "bddName", hozAlign: "left", }, { title: "Actions", field: "id", width: 120, hozAlign: "center", headerSort: false, formatter: (cell) => { const id = cell.getValue(); // Return a button that Stimulus can listen to return `
`; } }); } const tabulator = new Tabulator("#tabulator-projectListOrganization", { langs: TABULATOR_FR_LANG, locale: "fr", ajaxURL: `/project/organization/data`, ajaxConfig: "GET", pagination: true, paginationMode: "remote", paginationSize: 15, ajaxParams: {orgId: this.orgIdValue}, ajaxResponse: (url, params, response) => response, paginationDataSent: {page: "page", size: "size"}, paginationDataReceived: {last_page: "last_page"}, ajaxSorting: true, ajaxFiltering: true, filterMode: "remote", ajaxURLGenerator: function(url, config, params) { let queryParams = new URLSearchParams(); queryParams.append('orgId', params.orgId); queryParams.append('page', params.page || 1); queryParams.append('size', params.size || 15); // Add filters if (params.filter) { params.filter.forEach(filter => { queryParams.append(`filter[${filter.field}]`, filter.value); }); } return `${url}?${queryParams.toString()}`; }, rowHeight: 60, layout: "fitColumns", // activate French columns }) } async loadApplications() { try { const response = await fetch('/application/data/all'); const apps = await response.json(); this.appListTarget.innerHTML = apps.map(app => `
`).join(''); } catch (error) { this.appListTarget.innerHTML = '
Erreur de chargement.
'; } } async submitForm(event) { event.preventDefault(); const formData = new FormData(event.target); const payload = { organizationId: this.orgIdValue, applications: formData.getAll('applications[]') }; // Only include name if it wasn't disabled (new projects) if (!this.nameInputTarget.disabled) { payload.name = formData.get('name'); } const url = this.currentProjectId ? `/project/edit/${this.currentProjectId}/ajax` : `/project/new/ajax`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (response.ok) { this.modal.hide(); // Use Tabulator's setData() instead of reload() for better UX if possible location.reload(); } else { if (response.status === 409) { alert("Un projet avec ce nom existe déjà. Veuillez choisir un nom différent."); } } } async openEditModal(event) { const projectId = event.currentTarget.dataset.id; this.currentProjectId = projectId; this.modal.show(); this.nameInputTarget.disabled = true; this.formTitleTarget.textContent = "Modifier le projet"; try { // 1. Ensure checkboxes are loaded first const apps = await this.fetchAndRenderApplications(this.appListTarget); // 2. Fetch the project data const response = await fetch(`/project/data/${projectId}`); const project = await response.json(); // 3. Set the name this.nameInputTarget.value = project.name; // 4. Check the boxes // We look for all checkboxes inside our appList target const checkboxes = this.appListTarget.querySelectorAll('input[type="checkbox"]'); checkboxes.forEach(cb => { cb.checked = project.applications.includes(cb.value); }); } catch (error) { console.error("Error loading project data", error); alert("Erreur lors de la récupération des données du projet."); } } // Update your openCreateModal to reset the state async openCreateModal() { this.currentProjectId = null; this.modal.show(); this.nameInputTarget.disabled = false; this.nameInputTarget.value = ""; this.formTitleTarget.textContent = "Nouveau Projet"; await this.fetchAndRenderApplications(); } async deleteProject(event) { const projectId = event.currentTarget.dataset.id; if (!confirm("Êtes-vous sûr de vouloir supprimer ce projet ?")) { return; } try { const response = await fetch(`/project/delete/${projectId}/ajax`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, }); if (response.ok) { location.reload(); } }catch (error) { console.error("Error deleting project", error); alert("Erreur lors de la suppression du projet."); } } }