Easy_solution/assets/controllers/organization_controller.js

226 lines
7.6 KiB
JavaScript

import {Controller} from '@hotwired/stimulus'
// Important: include a build with Ajax + pagination (TabulatorFull is simplest)
import {TabulatorFull as Tabulator} from 'tabulator-tables';
import {eyeIconLink, TABULATOR_FR_LANG} from "../js/global.js";
import { Modal } from "bootstrap";
export default class extends Controller {
static values = {
id: Number,
activities: Boolean,
table: Boolean,
sadmin: Boolean,
user: Number
};
static targets = ["activityList", "emptyMessage", "modal", "modalTitle", "nameInput", "emailInput", "numberInput", "addressInput"];
connect() {
if(this.activitiesValue){
this.loadActivities();
setInterval(() => {
this.loadActivities();
}, 300000); // Refresh every 5 minutes
}
if (this.tableValue && this.sadminValue) {
this.table();
}
if (this.hasModalTarget) {
this.modal = new Modal(this.modalTarget);
this.currentOrgId = null;
}
}
table(){
const table = new Tabulator("#tabulator-org", {
// Register locales here
langs: TABULATOR_FR_LANG,
placeholder: "Aucun résultat trouvé pour cette recherche",
locale: "fr", //'en' for English, 'fr' for French (en is default, no need to include it)
ajaxURL: `/organization/data`,
ajaxConfig: "GET",
pagination: true,
paginationMode: "remote",
paginationSize: 10,
//paginationSizeSelector: [5, 10, 20, 50], // Désactivé pour l'instant car jpp faire de jolie style
ajaxResponse: (url, params, response) => response,
paginationDataSent: { page: "page", size: "size" },
paginationDataReceived: { last_page: "last_page",
data: "data"},
filterMode: "remote",
ajaxURLGenerator: function(url, config, params) {
let queryParams = new URLSearchParams();
queryParams.append('page', params.page || 1);
queryParams.append('size', params.size || 10);
// Add filters
if (params.filter) {
params.filter.forEach(filter => {
queryParams.append(`filter[${filter.field}]`, filter.value);
});
}
return `${url}?${queryParams.toString()}`;
},
ajaxSorting: true,
ajaxFiltering: true,
rowHeight: 60,
layout: "fitColumns",
columns: [
{
title: "Logo",
field: "logoUrl",
formatter: "image",
formatterParams: {
height: "50px",
width: "50px",
urlPrefix: "",
urlSuffix: "",
},
width: 100,
},
{title: "Nom", field: "name", headerFilter: "input", widthGrow: 2, vertAlign: "middle", headerHozAlign: "left"},
{title: "Email", field: "email", headerFilter: "input", widthGrow: 2, vertAlign: "middle", hozAlign: "center"},
{
title: "Actions",
field: "showUrl",
hozAlign: "center",
width: 100,
vertAlign: "middle",
headerSort: false,
formatter: (cell) => {
const url = cell.getValue();
if (url) {
return eyeIconLink(url);
}
return '';
}
}],
});
}
async loadActivities() {
try {
// 1. Fetch the data using the ID from values
const response = await fetch(`/actions/organization/${this.idValue}/activities-ajax`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const activities = await response.json();
// 2. Render
this.renderActivities(activities);
} catch (error) {
console.error('Error fetching activities:', error);
this.activityListTarget.innerHTML = `<div class="text-danger">Erreur lors du chargement.</div>`;
}
}
renderActivities(activities) {
// Clear the loading spinner
this.activityListTarget.innerHTML = '';
if (activities.length === 0) {
// Show empty message
this.activityListTarget.innerHTML = this.emptyMessageTarget.innerHTML;
return;
}
// Loop through JSON and build HTML
const html = activities.map(activity => {
return `
<div class="card shadow-sm mb-3 border-0 bg-white rounded-end"
style="border-left: 6px solid ${activity.color} !important;">
<div class="card-header bg-transparent border-0 pb-0 pt-3">
<h6 class="text-muted text-uppercase fw-bold mb-0" style="font-size: 0.85rem;">
${activity.date}
</h6>
</div>
<div class="card-body pt-2 pb-4">
<div class="card-text fs-5 lh-sm">
<span class="fw-bold text-dark">${activity.userName}</span>
<div class="text-secondary mt-1">${activity.actionType}</div>
</div>
</div>
</div>
`;
}).join('');
//com
this.activityListTarget.innerHTML = html;
}
openCreateModal() {
this.currentOrgId = null;
this.modalTitleTarget.textContent = "Créer une organisation";
this.resetForm();
this.modal.show();
}
async openEditModal(event) {
this.currentOrgId = event.currentTarget.dataset.id;
this.modalTitleTarget.textContent = "Modifier l'organisation";
try {
const response = await fetch(`/organization/${this.currentOrgId}`);
const data = await response.json();
// Fill targets
this.nameInputTarget.value = data.name;
this.emailInputTarget.value = data.email;
this.numberInputTarget.value = data.number || '';
this.addressInputTarget.value = data.address || '';
this.modal.show();
} catch (error) {
alert("Erreur lors du chargement des données.");
}
}
async submitForm(event) {
event.preventDefault();
const formData = new FormData(event.target);
const method = this.currentOrgId ? 'PUT' : 'POST';
const url = this.currentOrgId ? `/organization/${this.currentOrgId}` : `/organization/`;
if (this.currentOrgId) {
formData.append('_method', 'PUT');
}
try {
const response = await fetch(url, {
method: 'POST',
body: formData,
headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
if (response.ok) {
this.modal.hide();
location.reload();
} else {
const result = await response.json();
alert(result.error || "Une erreur est survenue.");
}
} catch (e) {
alert("Erreur réseau.");
}
}
resetForm() {
this.nameInputTarget.value = "";
this.emailInputTarget.value = "";
this.numberInputTarget.value = "";
this.addressInputTarget.value = "";
}
}