151 lines
6.0 KiB
JavaScript
151 lines
6.0 KiB
JavaScript
/**
|
||
* Compte d'accès depuis la fiche des agents (`PTA.modules.agentAccess`),
|
||
* écran manage_agents.php — V7.28.
|
||
*
|
||
* Pose sur chaque ligne du tableau des agents un bouton qui COUPE ou RÉTABLIT
|
||
* l'accès de l'agent à l'application. C'est le geste courant — un départ, un
|
||
* arrêt long, un retour — là où l'écran Administration porte la distribution des
|
||
* jetons elle-même.
|
||
*
|
||
* CE QUE LE BOUTON NE FAIT PAS : il ne touche ni au jeton (désactiver puis
|
||
* réactiver rend le MÊME jeton valable), ni à la fiche de l'agent, qui reste
|
||
* planifiable. Il ne crée pas non plus de compte : un agent qui n'en a pas
|
||
* encore l'obtient depuis Administration, seul écran qui sache afficher un jeton
|
||
* fraîchement produit.
|
||
*
|
||
* Il réutilise les endpoints de la délégation V7.27 (api/acces_comptes.php et
|
||
* api/acces_compte_statut.php) : mêmes gardes serveur, même liste blanche de
|
||
* rôles, même journalisation. Rien de neuf côté droits.
|
||
*
|
||
* L'état des comptes N'EST PAS rendu par PHP mais chargé par ce module : le HTML
|
||
* servi ne porte ainsi aucune information sur les comptes, comme sur l'écran
|
||
* DSI.
|
||
*/
|
||
(() => {
|
||
'use strict';
|
||
const PTA = window.PTA;
|
||
if (!PTA) return;
|
||
|
||
const { apiJson } = PTA.utils;
|
||
|
||
const corps = () => document.querySelector('#agent-assignment-body');
|
||
|
||
/** Comptes d'accès des agents, indexés par identifiant d'agent. */
|
||
let comptesParAgent = new Map();
|
||
let chargement = false;
|
||
|
||
function message(texte, type = 'info') {
|
||
const boite = document.querySelector('#assignment-message');
|
||
if (!boite) return;
|
||
boite.className = texte ? `message message-${type}` : 'message';
|
||
boite.textContent = texte;
|
||
}
|
||
|
||
/**
|
||
* Met un bouton de ligne à l'état du compte correspondant.
|
||
*
|
||
* Trois états, et un seul est actionnable :
|
||
* - compte actif → « Couper l'accès » ;
|
||
* - compte coupé → « Rétablir l'accès » ;
|
||
* - aucun compte → bouton inerte, qui dit où en créer un.
|
||
*/
|
||
function decorerLigne(ligne) {
|
||
const bouton = ligne.querySelector('.agent-access-toggle');
|
||
if (!bouton) return;
|
||
|
||
const agentId = Number(ligne.dataset.agentId);
|
||
const compte = comptesParAgent.get(agentId);
|
||
|
||
if (!compte) {
|
||
bouton.disabled = true;
|
||
bouton.textContent = 'Sans compte d’accès';
|
||
bouton.title = 'Cet agent n’a pas encore de jeton. Créez son compte depuis l’onglet Administration, section « Jetons d’accès ».';
|
||
delete bouton.dataset.compteId;
|
||
delete bouton.dataset.actif;
|
||
return;
|
||
}
|
||
|
||
bouton.disabled = false;
|
||
bouton.dataset.compteId = String(compte.id_compte);
|
||
bouton.dataset.actif = compte.actif ? '1' : '0';
|
||
bouton.textContent = compte.actif ? 'Couper l’accès' : 'Rétablir l’accès';
|
||
bouton.title = compte.actif
|
||
? 'Désactive le compte : l’agent ne pourra plus se connecter. Son jeton reste valable et resservira au rétablissement.'
|
||
: 'Réactive le compte : l’agent pourra de nouveau se connecter avec le jeton qu’il détient déjà.';
|
||
bouton.classList.toggle('button-danger', compte.actif);
|
||
bouton.classList.toggle('button-secondary', !compte.actif);
|
||
}
|
||
|
||
/** Applique l'état chargé à toutes les lignes présentes. */
|
||
function decorerToutesLesLignes() {
|
||
corps()?.querySelectorAll('tr[data-agent-id]').forEach(decorerLigne);
|
||
}
|
||
|
||
/**
|
||
* Recharge l'état des comptes agents.
|
||
*
|
||
* L'échec est SILENCIEUX sur le tableau : les boutons restent inertes avec
|
||
* leur libellé d'attente, et la page des agents continue de fonctionner. Une
|
||
* commodité ne doit pas empêcher de consulter ou de modifier une fiche.
|
||
*/
|
||
async function refresh() {
|
||
if (!corps() || chargement) return;
|
||
chargement = true;
|
||
try {
|
||
const donnees = await apiJson('api/acces_comptes.php?role=AGENT');
|
||
comptesParAgent = new Map(
|
||
(donnees.comptes || [])
|
||
.filter((compte) => compte.id_agent !== null)
|
||
.map((compte) => [Number(compte.id_agent), compte])
|
||
);
|
||
decorerToutesLesLignes();
|
||
} catch (erreur) {
|
||
message(`État des comptes d’accès indisponible : ${erreur.message}`, 'warning');
|
||
} finally {
|
||
chargement = false;
|
||
}
|
||
}
|
||
|
||
/** Coupe ou rétablit l'accès de l'agent d'une ligne. */
|
||
async function basculer(evenement) {
|
||
const bouton = evenement.target.closest('.agent-access-toggle');
|
||
if (!bouton || bouton.disabled) return;
|
||
|
||
const ligne = bouton.closest('tr[data-agent-id]');
|
||
const compteId = Number(bouton.dataset.compteId);
|
||
const actif = bouton.dataset.actif === '1';
|
||
const titulaire = ligne?.querySelector('.agent-row-name')?.textContent?.trim() || 'cet agent';
|
||
|
||
if (actif && !window.confirm(`Couper l’accès de ${titulaire} ? Il ne pourra plus se connecter, et sa session en cours se refermera à sa prochaine action. Son jeton reste valable pour un rétablissement.`)) {
|
||
return;
|
||
}
|
||
|
||
bouton.disabled = true;
|
||
try {
|
||
const donnees = await apiJson('api/acces_compte_statut.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
csrf_token: window.PTA_CONFIG.csrfToken,
|
||
compte_id: compteId,
|
||
action: actif ? 'DESACTIVER' : 'ACTIVER',
|
||
}),
|
||
});
|
||
message(donnees.message, 'success');
|
||
await refresh();
|
||
} catch (erreur) {
|
||
message(erreur.message, 'error');
|
||
bouton.disabled = false;
|
||
}
|
||
}
|
||
|
||
function init() {
|
||
// Le module ne sert que sur l'écran des agents : ailleurs, il se retire.
|
||
if (!corps()) return;
|
||
corps().addEventListener('click', basculer);
|
||
refresh();
|
||
}
|
||
|
||
PTA.modules.agentAccess = { init, refresh };
|
||
})();
|