227 lines
7.7 KiB
JavaScript
227 lines
7.7 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 {capitalizeFirstLetter, 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');
|
|
}
|
|
formData.set('name', capitalizeFirstLetter(formData.get('name')));
|
|
|
|
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 = "";
|
|
}
|
|
} |