840 lines
35 KiB
JavaScript
840 lines
35 KiB
JavaScript
import {Controller} from '@hotwired/stimulus';
|
|
import Choices from 'choices.js';
|
|
import {TabulatorFull as Tabulator} from 'tabulator-tables';
|
|
import {activateUserIcon, deactivateUserIcon, eyeIconLink, sendEmailIcon, TABULATOR_FR_LANG} from "../js/global.js";
|
|
|
|
|
|
export default class extends Controller {
|
|
static values = {
|
|
rolesArray: Array,
|
|
selectedRoleIds: Array,
|
|
id: Number,
|
|
list: Boolean,
|
|
listOrganization: Boolean,
|
|
new: Boolean,
|
|
admin: Boolean,
|
|
listSmall: Boolean,
|
|
statut: Boolean,
|
|
orgId: Number
|
|
}
|
|
|
|
static targets = ["select"];
|
|
|
|
connect() {
|
|
this.roleSelect();
|
|
if (this.listValue) {
|
|
this.table();
|
|
}
|
|
if (this.newValue) {
|
|
this.tableNew();
|
|
}
|
|
if (this.adminValue) {
|
|
this.tableSmallAdmin();
|
|
}
|
|
if (this.listOrganizationValue) {
|
|
this.tableOrganization()
|
|
}
|
|
|
|
}
|
|
|
|
roleSelect() {
|
|
if (this.hasSelectTarget) {
|
|
const choicesData = this.rolesArrayValue.map(role => ({
|
|
value: role.id,
|
|
label: role.name,
|
|
selected: this.selectedRoleIdsValue.includes(role.id)
|
|
}));
|
|
|
|
new Choices(this.selectTarget, {
|
|
choices: choicesData,
|
|
removeItemButton: true,
|
|
placeholder: true,
|
|
placeholderValue: 'Ajouter un ou plusieurs rôles',
|
|
});
|
|
}
|
|
}
|
|
|
|
// TODO: vérifier le style des header filter et vertAlign/hozalign
|
|
table() {
|
|
const columns = [
|
|
{
|
|
title: "",
|
|
field: "isConnected",
|
|
width: 40, // small column
|
|
hozAlign: "center",
|
|
vertAlign: "middle",
|
|
headerSort: false,
|
|
tooltip: false,
|
|
formatter: (cell) => {
|
|
const online = !!cell.getValue();
|
|
const color = online ? "#80F20E" : "#E42E31"; // green/red
|
|
return `<span class="status-dot" style="
|
|
display:inline-block;
|
|
width:10px;height:10px;
|
|
border-radius:50%;
|
|
background:${color};
|
|
"></span>`;
|
|
},
|
|
// Optional: for accessibility
|
|
formatterPrint: (cell) => (cell.getValue() ? "online" : "offline"),
|
|
formatterClipboard: (cell) => (cell.getValue() ? "online" : "offline"),
|
|
},
|
|
{
|
|
title: "Profil",
|
|
field: "pictureUrl",
|
|
width: 80,
|
|
hozAlign: "center",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const data = cell.getRow().getData();
|
|
const url = cell.getValue();
|
|
const first = (s) => (typeof s === "string" && s.length ? s.trim()[0].toUpperCase() : "");
|
|
const initials = `${first(data.name)}${first(data.prenom)}`;
|
|
|
|
// wrapper is for centering and circle clipping
|
|
const wrapper = document.createElement("div");
|
|
wrapper.className = "avatar-wrapper";
|
|
// same size for both cases
|
|
wrapper.style.width = "40px";
|
|
wrapper.style.height = "40px";
|
|
wrapper.style.display = "flex";
|
|
wrapper.style.alignItems = "center";
|
|
wrapper.style.justifyContent = "center";
|
|
wrapper.style.borderRadius = "50%";
|
|
wrapper.style.overflow = "hidden"; // ensure image clips to circle
|
|
|
|
if (!url) {
|
|
wrapper.style.background = "#6c757d"; // gray background
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "14px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
return wrapper;
|
|
}
|
|
|
|
// Image case: make it fill the same wrapper
|
|
const img = document.createElement("img");
|
|
img.src = url;
|
|
img.alt = initials || "avatar";
|
|
img.style.width = "100%";
|
|
img.style.height = "100%";
|
|
img.style.objectFit = "cover"; // keep aspect and cover circle
|
|
wrapper.appendChild(img);
|
|
|
|
// Optional: fallback if image fails
|
|
img.addEventListener("error", () => {
|
|
wrapper.innerHTML = "";
|
|
wrapper.style.background = "#6c757d";
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "12px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
});
|
|
|
|
return wrapper;
|
|
},
|
|
},
|
|
{title: "<b>Nom</b>", field: "name", headerFilter: "input", widthGrow: 2, vertAlign: "middle"},
|
|
{title: "<b>Prénom</b>", field: "prenom", headerFilter: "input", widthGrow: 2, vertAlign: "middle"},
|
|
{title: "<b>Email</b>", field: "email", headerFilter: "input", widthGrow: 3, vertAlign: "middle"},
|
|
{
|
|
title: "<b>Statut</b>", field: "statut", vertAlign: "middle",
|
|
formatter: (cell) => {
|
|
const statut = cell.getValue();
|
|
if (statut) {
|
|
return `<span class="badge bg-success">Actif</span>`
|
|
} else {
|
|
return `<span class="badge bg-secondary">Inactif</span>`
|
|
}
|
|
}
|
|
},
|
|
{
|
|
title: "<b>Actions</b>",
|
|
field: "showUrl",
|
|
vertAlign: "middle",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const url = cell.getValue();
|
|
if (!url) return '';
|
|
|
|
const rowData = cell.getRow().getData();
|
|
const userId = rowData.id;
|
|
const statut = rowData.statut;
|
|
|
|
// Decide which action (deactivate vs activate)
|
|
const isActive = Boolean(statut);
|
|
|
|
const actionClass = isActive ? 'deactivate-user' : 'activate-user';
|
|
const actionTitle = isActive ? 'Désactiver' : 'Réactiver';
|
|
const actionColorClass = isActive ? 'color-secondary' : 'color-primary';
|
|
|
|
// SVGs
|
|
const deactivateSvg = deactivateUserIcon();
|
|
|
|
const activateSvg = activateUserIcon();
|
|
const actionSvg = isActive ? deactivateSvg : activateSvg;
|
|
|
|
return `
|
|
<div class="d-flex gap-2 align-content-center">
|
|
${eyeIconLink(url)}
|
|
|
|
<a href="#"
|
|
class="${actionColorClass} ${actionClass} pt-3"
|
|
data-id="${userId}"
|
|
title="${actionTitle}">
|
|
${actionSvg}
|
|
</a>
|
|
</div>
|
|
`;
|
|
},
|
|
|
|
cellClick: function (e, cell) {
|
|
const target = e.target.closest('a');
|
|
if (!target) return;
|
|
|
|
// Deactivate
|
|
if (target.classList.contains('deactivate-user')) {
|
|
e.preventDefault();
|
|
const userId = target.getAttribute('data-id');
|
|
if (confirm('Voulez-vous vraiment désactiver cet utilisateur ?')) {
|
|
const formData = new FormData();
|
|
formData.append('status', 'deactivate');
|
|
|
|
fetch(`/user/activeStatus/${userId}`, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {'X-Requested-With': 'XMLHttpRequest'}
|
|
})
|
|
.then(async (response) => {
|
|
if (response.ok) {
|
|
const data = cell.getRow().getData();
|
|
data.statut = false;
|
|
cell.getRow().reformat();
|
|
} else {
|
|
const text = await response.text();
|
|
alert('Erreur lors de la désactivation: ' + text);
|
|
}
|
|
})
|
|
.catch(() => alert('Erreur lors de la désactivation'));
|
|
}
|
|
}
|
|
|
|
// Activate
|
|
if (target.classList.contains('activate-user')) {
|
|
e.preventDefault();
|
|
const userId = target.getAttribute('data-id');
|
|
if (confirm('Voulez-vous réactiver cet utilisateur ?')) {
|
|
const formData = new FormData();
|
|
formData.append('status','activate');
|
|
|
|
fetch(`/user/activeStatus/${userId}`, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {'X-Requested-With': 'XMLHttpRequest'}
|
|
})
|
|
.then(async (response) => {
|
|
if (response.ok) {
|
|
// Switch status back to active and re-render row
|
|
const data = cell.getRow().getData();
|
|
data.statut = true;
|
|
cell.getRow().reformat();
|
|
} else {
|
|
const text = await response.text();
|
|
alert('Erreur lors de la réactivation: ' + text);
|
|
}
|
|
})
|
|
.catch(() => alert('Erreur lors de la réactivation'));
|
|
}
|
|
}
|
|
}
|
|
}];
|
|
const tabulator = new Tabulator("#tabulator-userList", {
|
|
langs: TABULATOR_FR_LANG,
|
|
locale: "fr",
|
|
ajaxURL: "/user/data",
|
|
ajaxConfig: "GET",
|
|
pagination: true,
|
|
paginationMode: "remote",
|
|
paginationSize: 10,
|
|
|
|
ajaxResponse: (url, params, response) => response,
|
|
paginationDataSent: {page: "page", size: "size"},
|
|
paginationDataReceived: {last_page: "last_page"},
|
|
|
|
ajaxSorting: true,
|
|
ajaxFiltering: true,
|
|
filterMode: "remote",
|
|
|
|
// Add this to send filter data
|
|
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()}`;
|
|
},
|
|
|
|
rowHeight: 60,
|
|
layout: "fitColumns",
|
|
columns
|
|
});
|
|
};
|
|
|
|
|
|
tableNew() {
|
|
const columns = [
|
|
{
|
|
title: "Profil",
|
|
field: "pictureUrl",
|
|
width: 80,
|
|
hozAlign: "center",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const data = cell.getRow().getData();
|
|
const url = cell.getValue();
|
|
const first = (s) => (typeof s === "string" && s.length ? s.trim()[0].toUpperCase() : "");
|
|
const initials = `${data.initials}`;
|
|
|
|
const wrapper = document.createElement("div");
|
|
wrapper.className = "avatar-wrapper";
|
|
// same size for both cases
|
|
wrapper.style.width = "40px";
|
|
wrapper.style.height = "40px";
|
|
wrapper.style.display = "flex";
|
|
wrapper.style.alignItems = "center";
|
|
wrapper.style.justifyContent = "center";
|
|
wrapper.style.borderRadius = "50%";
|
|
wrapper.style.overflow = "hidden"; // ensure image clips to circle
|
|
|
|
if (!url) {
|
|
wrapper.style.background = "#6c757d"; // gray background
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "14px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
return wrapper;
|
|
}
|
|
|
|
// Image case: make it fill the same wrapper
|
|
const img = document.createElement("img");
|
|
img.src = url;
|
|
img.alt = initials || "avatar";
|
|
img.style.width = "100%";
|
|
img.style.height = "100%";
|
|
img.style.objectFit = "cover"; // keep aspect and cover circle
|
|
wrapper.appendChild(img);
|
|
|
|
// Optional: fallback if image fails
|
|
img.addEventListener("error", () => {
|
|
wrapper.innerHTML = "";
|
|
wrapper.style.background = "#6c757d";
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "12px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
});
|
|
|
|
return wrapper;
|
|
},
|
|
},
|
|
{title: "<b>Email</b>", field: "email", widthGrow: 3, vertAlign: "middle"},
|
|
{
|
|
title: "<b>Actions</b>",
|
|
field: "showUrl",
|
|
hozAlign: "center",
|
|
width: 100,
|
|
vertAlign: "middle",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const url = cell.getValue();
|
|
if (url) {
|
|
return eyeIconLink(url);
|
|
}
|
|
return '';
|
|
}
|
|
}
|
|
];
|
|
|
|
|
|
const tabulator = new Tabulator("#tabulator-userListSmall", {
|
|
|
|
locale: "fr", //'en' for English, 'fr' for French (en is default, no need to include it)
|
|
ajaxURL: "/user/data/new",
|
|
|
|
ajaxConfig: "GET",
|
|
pagination: false,
|
|
paginationMode: "remote",
|
|
// paginationSize: 5,
|
|
ajaxParams: {orgId: this.orgIdValue},
|
|
langs: TABULATOR_FR_LANG,
|
|
ajaxResponse: (url, params, response) => response.data,
|
|
// paginationDataSent: {page: "page", size: "size"},
|
|
// paginationDataReceived: {last_page: "last_page"},
|
|
|
|
// ajaxSorting: true,
|
|
// ajaxFiltering: true,
|
|
rowHeight: 60,
|
|
layout: "fitColumns", // activate French
|
|
|
|
columns
|
|
});
|
|
}
|
|
|
|
tableSmallAdmin() {
|
|
const columns = [
|
|
{
|
|
title: "Profil",
|
|
field: "pictureUrl",
|
|
width: 80,
|
|
hozAlign: "center",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const data = cell.getRow().getData();
|
|
const url = cell.getValue();
|
|
const first = (s) => (typeof s === "string" && s.length ? s.trim()[0].toUpperCase() : "");
|
|
const initials = `${data.initials}`;
|
|
|
|
const wrapper = document.createElement("div");
|
|
wrapper.className = "avatar-wrapper";
|
|
// same size for both cases
|
|
wrapper.style.width = "40px";
|
|
wrapper.style.height = "40px";
|
|
wrapper.style.display = "flex";
|
|
wrapper.style.alignItems = "center";
|
|
wrapper.style.justifyContent = "center";
|
|
wrapper.style.borderRadius = "50%";
|
|
wrapper.style.overflow = "hidden"; // ensure image clips to circle
|
|
|
|
if (!url) {
|
|
wrapper.style.background = "#6c757d"; // gray background
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "14px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
return wrapper;
|
|
}
|
|
|
|
// Image case: make it fill the same wrapper
|
|
const img = document.createElement("img");
|
|
img.src = url;
|
|
img.alt = initials || "avatar";
|
|
img.style.width = "100%";
|
|
img.style.height = "100%";
|
|
img.style.objectFit = "cover"; // keep aspect and cover circle
|
|
wrapper.appendChild(img);
|
|
|
|
// Optional: fallback if image fails
|
|
img.addEventListener("error", () => {
|
|
wrapper.innerHTML = "";
|
|
wrapper.style.background = "#6c757d";
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "12px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
});
|
|
|
|
return wrapper;
|
|
},
|
|
},
|
|
{title: "<b>Email</b>", field: "email", widthGrow: 3, vertAlign: "middle"},
|
|
{
|
|
title: "<b>Actions</b>",
|
|
field: "showUrl",
|
|
hozAlign: "center",
|
|
width: 100,
|
|
vertAlign: "middle",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const url = cell.getValue();
|
|
if (url) {
|
|
eyeIconLink(url);
|
|
}
|
|
return '';
|
|
}
|
|
}
|
|
];
|
|
|
|
|
|
const tabulator = new Tabulator("#tabulator-userListSmallAdmin", {
|
|
|
|
locale: "fr", //'en' for English, 'fr' for French (en is default, no need to include it)
|
|
ajaxURL: "/user/data/admin",
|
|
|
|
ajaxConfig: "GET",
|
|
pagination: false,
|
|
paginationMode: "remote",
|
|
// paginationSize: 5,
|
|
ajaxParams: {orgId: this.orgIdValue},
|
|
langs: TABULATOR_FR_LANG,
|
|
ajaxResponse: (url, params, response) => response.data,
|
|
// paginationDataSent: {page: "page", size: "size"},
|
|
// paginationDataReceived: {last_page: "last_page"},
|
|
|
|
// ajaxSorting: true,
|
|
// ajaxFiltering: true,
|
|
rowHeight: 60,
|
|
layout: "fitColumns", // activate French
|
|
|
|
columns
|
|
});
|
|
}
|
|
|
|
tableOrganization() {
|
|
|
|
const columns = [
|
|
{
|
|
title: "",
|
|
field: "isConnected",
|
|
width: 40, // small column
|
|
hozAlign: "center",
|
|
vertAlign: "middle",
|
|
headerSort: false,
|
|
tooltip: false,
|
|
formatter: (cell) => {
|
|
const online = !!cell.getValue();
|
|
const color = online ? "#80F20E" : "#E42E31"; // green/red
|
|
return `<span class="status-dot" style="
|
|
display:inline-block;
|
|
width:10px;height:10px;
|
|
border-radius:50%;
|
|
background:${color};
|
|
"></span>`;
|
|
},
|
|
// Optional: for accessibility
|
|
formatterPrint: (cell) => (cell.getValue() ? "online" : "offline"),
|
|
formatterClipboard: (cell) => (cell.getValue() ? "online" : "offline"),
|
|
},
|
|
{
|
|
title: "Profil",
|
|
field: "pictureUrl",
|
|
width: 80,
|
|
hozAlign: "center",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const data = cell.getRow().getData();
|
|
const url = cell.getValue();
|
|
const first = (s) => (typeof s === "string" && s.length ? s.trim()[0].toUpperCase() : "");
|
|
const initials = `${first(data.name)}${first(data.prenom)}`;
|
|
|
|
const wrapper = document.createElement("div");
|
|
wrapper.className = "avatar-wrapper";
|
|
// same size for both cases
|
|
wrapper.style.width = "40px";
|
|
wrapper.style.height = "40px";
|
|
wrapper.style.display = "flex";
|
|
wrapper.style.alignItems = "center";
|
|
wrapper.style.justifyContent = "center";
|
|
wrapper.style.borderRadius = "50%";
|
|
wrapper.style.overflow = "hidden"; // ensure image clips to circle
|
|
|
|
if (!url) {
|
|
wrapper.style.background = "#6c757d"; // gray background
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "14px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
return wrapper;
|
|
}
|
|
|
|
// Image case: make it fill the same wrapper
|
|
const img = document.createElement("img");
|
|
img.src = url;
|
|
img.alt = initials || "avatar";
|
|
img.style.width = "100%";
|
|
img.style.height = "100%";
|
|
img.style.objectFit = "cover"; // keep aspect and cover circle
|
|
wrapper.appendChild(img);
|
|
|
|
// Optional: fallback if image fails
|
|
img.addEventListener("error", () => {
|
|
wrapper.innerHTML = "";
|
|
wrapper.style.background = "#6c757d";
|
|
const span = document.createElement("span");
|
|
span.className = "avatar-initials";
|
|
span.style.color = "#fff";
|
|
span.style.fontWeight = "600";
|
|
span.style.fontSize = "12px";
|
|
span.textContent = initials || "•";
|
|
wrapper.appendChild(span);
|
|
});
|
|
|
|
return wrapper;
|
|
},
|
|
},
|
|
{title: "<b>Nom</b>", field: "name", headerFilter: "input", widthGrow: 2, vertAlign: "middle"},
|
|
{title: "<b>Prénom</b>", field: "prenom", headerFilter: "input", widthGrow: 2, vertAlign: "middle"},
|
|
{title: "<b>Email</b>", field: "email", headerFilter: "input", widthGrow: 3, vertAlign: "middle"},
|
|
{
|
|
title: "<b>Statut</b>", field: "statut", vertAlign: "middle",
|
|
formatter: (cell) => {
|
|
const statut = cell.getValue();
|
|
if (statut === "INVITED") {
|
|
return `<span class="badge bg-primary">Invité</span>`
|
|
} else if (statut === "ACTIVE") {
|
|
return `<span class="badge bg-success">Actif</span>`
|
|
}else if( statut === "EXPIRED"){
|
|
return `<span class="badge bg-warning text-dark">Expiré</span>`
|
|
} else{
|
|
return `<span class="badge bg-secondary">Inactif</span>`
|
|
}
|
|
}
|
|
},
|
|
{
|
|
title: "<b>Actions</b>",
|
|
field: "showUrl",
|
|
vertAlign: "middle",
|
|
headerSort: false,
|
|
formatter: (cell) => {
|
|
const url = cell.getValue();
|
|
if (!url) return '';
|
|
|
|
const rowData = cell.getRow().getData();
|
|
const userId = rowData.id;
|
|
const statut = rowData.statut;
|
|
const orgId = this.orgIdValue;
|
|
|
|
// Check if user is expired
|
|
if (statut === "EXPIRED") {
|
|
return `
|
|
<div class="d-flex gap-2 align-content-center">
|
|
${eyeIconLink(url)}
|
|
|
|
${sendEmailIcon(userId, orgId)}
|
|
</div>
|
|
`;
|
|
}if (statut === "INVITED") {
|
|
return `
|
|
<div class="d-flex gap-2 align-content-center">
|
|
${eyeIconLink(url)}
|
|
</div>`;
|
|
}
|
|
|
|
// Decide which action (deactivate vs activate) for non-expired users
|
|
const isActive = (statut === "ACTIVE");
|
|
|
|
const actionClass = isActive ? 'deactivate-user' : 'activate-user';
|
|
const actionTitle = isActive ? 'Désactiver' : 'Réactiver';
|
|
const actionColorClass = isActive ? 'color-secondary' : 'color-primary';
|
|
|
|
// SVGs
|
|
const deactivateSvg = deactivateUserIcon();
|
|
|
|
const activateSvg = activateUserIcon();
|
|
|
|
const actionSvg = isActive ? deactivateSvg : activateSvg;
|
|
|
|
return `
|
|
<div class="d-flex gap-2 align-content-center">
|
|
${eyeIconLink(url)}
|
|
|
|
<a href="#"
|
|
class="${actionColorClass} ${actionClass} pt-3"
|
|
data-id="${userId}"
|
|
data-org-id="${orgId}"
|
|
title="${actionTitle}">
|
|
${actionSvg}
|
|
</a>
|
|
</div>
|
|
`;
|
|
},
|
|
|
|
cellClick: function (e, cell) {
|
|
const target = e.target.closest('a');
|
|
if (!target) return;
|
|
|
|
// Handle resend invitation for expired users
|
|
if (target.classList.contains('resend-invitation')) {
|
|
e.preventDefault();
|
|
const userId = target.getAttribute('data-id');
|
|
if (confirm('Voulez-vous renvoyer l\'invitation à cet utilisateur ?')) {
|
|
const formData = new FormData();
|
|
formData.append('organizationId', target.getAttribute('data-org-id'));
|
|
|
|
fetch(`/user/organization/resend-invitation/${userId}`, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {'X-Requested-With': 'XMLHttpRequest'}
|
|
})
|
|
.then(async (response) => {
|
|
if (response.ok) {
|
|
const data = cell.getRow().getData();
|
|
data.statut = "INVITED";
|
|
cell.getRow().reformat();
|
|
alert('Invitation renvoyée avec succès');
|
|
} else {
|
|
const text = await response.text();
|
|
alert('Erreur lors de l\'envoi : ' + text);
|
|
}
|
|
})
|
|
.catch(() => alert('Erreur lors de l\'envoi'));
|
|
}
|
|
}
|
|
|
|
// Deactivate
|
|
if (target.classList.contains('deactivate-user')) {
|
|
e.preventDefault();
|
|
const userId = target.getAttribute('data-id');
|
|
if (confirm('Voulez-vous vraiment désactiver cet utilisateur ?')) {
|
|
const formData = new FormData();
|
|
formData.append('status', 'deactivate');
|
|
formData.append('organizationId', target.getAttribute('data-org-id'));
|
|
|
|
fetch(`/user/organization/activateStatus/${userId}`, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {'X-Requested-With': 'XMLHttpRequest'}
|
|
})
|
|
.then(async (response) => {
|
|
if (response.ok) {
|
|
const data = cell.getRow().getData();
|
|
data.statut = "INACTIVE";
|
|
cell.getRow().reformat();
|
|
} else {
|
|
const text = await response.text();
|
|
alert('Erreur lors de la désactivation: ' + text);
|
|
}
|
|
})
|
|
.catch(() => alert('Erreur lors de la désactivation'));
|
|
}
|
|
}
|
|
|
|
// Activate
|
|
if (target.classList.contains('activate-user')) {
|
|
e.preventDefault();
|
|
const userId = target.getAttribute('data-id');
|
|
if (confirm('Voulez-vous réactiver cet utilisateur ?')) {
|
|
const formData = new FormData();
|
|
formData.append('status', 'activate');
|
|
formData.append('organizationId', target.getAttribute('data-org-id'));
|
|
|
|
fetch(`/user/organization/activateStatus/${userId}`, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {'X-Requested-With': 'XMLHttpRequest'}
|
|
})
|
|
.then(async (response) => {
|
|
if (response.ok) {
|
|
const data = cell.getRow().getData();
|
|
data.statut = "ACTIVE";
|
|
cell.getRow().reformat();
|
|
} else {
|
|
const text = await response.text();
|
|
alert('Erreur lors de la réactivation: ' + text);
|
|
}
|
|
})
|
|
.catch(() => alert('Erreur lors de la réactivation'));
|
|
}
|
|
}
|
|
}
|
|
}];
|
|
// if (this.statutValue) {
|
|
// columns.push(
|
|
// {
|
|
// title: "Statut", field: "role", // or any field you want
|
|
// headerSort: false,x
|
|
// hozAlign: "center",
|
|
// vertAlign: "middle",
|
|
// formatter: (cell) => {
|
|
// const row = cell.getRow();
|
|
// const current = cell.getValue() ?? "";
|
|
//
|
|
// const select = document.createElement("select");
|
|
// select.className = "table-select-action";
|
|
// // Options
|
|
// [
|
|
// {value: "", label: "Choisir..."},
|
|
// {value: "viewer", label: "Viewer"},
|
|
// {value: "editor", label: "Editor"},
|
|
// {value: "admin", label: "Admin"},
|
|
// ].forEach(opt => {
|
|
// const o = document.createElement("option");
|
|
// o.value = opt.value;
|
|
// o.textContent = opt.label;
|
|
// if (opt.value === current) o.selected = true;
|
|
// select.appendChild(o);
|
|
// });
|
|
//
|
|
// // Hook change
|
|
// select.addEventListener("change", (e) => {
|
|
// this.onSelectChange(row, e.target.value);
|
|
// });
|
|
//
|
|
// // Return a DOM node from a formatter → Tabulator will mount it
|
|
// return select;
|
|
// },
|
|
// // Optional: provide text for clipboard/print
|
|
// formatterClipboard: cell => cell.getValue(),
|
|
// formatterPrint: cell => cell.getValue(),
|
|
// },
|
|
// )
|
|
// }
|
|
const tabulator = new Tabulator("#tabulator-userListOrganization", {
|
|
langs: TABULATOR_FR_LANG,
|
|
locale: "fr",
|
|
ajaxURL: "/user/data/organization",
|
|
ajaxConfig: "GET",
|
|
ajaxParams: {orgId: this.orgIdValue},
|
|
|
|
pagination: true,
|
|
paginationMode: "remote",
|
|
paginationSize: 10,
|
|
|
|
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();
|
|
// console.log("orgId:", params.orgId);
|
|
queryParams.append('orgId', params.orgId);
|
|
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()}`;
|
|
},
|
|
rowHeight: 60,
|
|
layout: "fitColumns", // activate French
|
|
|
|
columns
|
|
});
|
|
};
|
|
} |