mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 16:07:10 +00:00
V1.18.19 Mise en place des collaborateurs
This commit is contained in:
+312
-17
@@ -455,6 +455,90 @@
|
||||
}
|
||||
.postit .pastille-urgence-postit.rouge{ background:#c0392b; }
|
||||
.postit .pastille-urgence-postit.orange{ background:#ff5a1f; }
|
||||
|
||||
/* Portraits des assistants, écran 2 (9 septembre 2026 — voir journal).
|
||||
Même principe d'attachement que #postits-layer pour le fond liège :
|
||||
#assistants-layer est déplacé (au sens JS) à l'intérieur de la slide du
|
||||
fond "tasseaux gris" (index 1) à chaque fois qu'elle existe, voir
|
||||
creerFondSlide()/changerFond() plus bas — invisible tant qu'un autre
|
||||
fond est affiché, sans dupliquer sa logique de position. position:absolute
|
||||
(pas fixed) : positionné par rapport à ce conteneur local (lui-même
|
||||
inset:0 dans la slide, elle-même calée sur le rectangle "contain"), pas
|
||||
par rapport à la fenêtre — voir positionner().
|
||||
Nombre de colonnes non codé en dur (décision de Jean-Marc, 9 septembre
|
||||
2026) : une carte par agent réellement renvoyé par agents.php, largeur
|
||||
de colonne = largeur totale / nombre d'agents — s'adapte donc tout seul
|
||||
si un agent est ajouté ou retiré, sans repasser par ce fichier. */
|
||||
#assistants-layer{
|
||||
position:absolute;
|
||||
inset:0;
|
||||
}
|
||||
.assistant-carte{
|
||||
position:absolute;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
pointer-events:none; /* purement visuel pour l'instant, comme les post-its */
|
||||
}
|
||||
.assistant-cadre{
|
||||
background:#fff;
|
||||
box-shadow:2px 4px 8px rgba(0,0,0,.35);
|
||||
box-sizing:border-box;
|
||||
display:block;
|
||||
}
|
||||
.assistant-photo{
|
||||
display:block;
|
||||
width:100%;
|
||||
height:100%;
|
||||
object-fit:cover;
|
||||
}
|
||||
/* Repli visuel pour un agent sans AGN_Photo renseignée (ex. le temps que
|
||||
Jean-Marc dépose la photo) : même esprit que le "?" utilisé dans les
|
||||
essais visuels, jamais un cadre vide sans explication. */
|
||||
.assistant-photo-repli{
|
||||
display:flex;align-items:center;justify-content:center;
|
||||
width:100%;height:100%;
|
||||
background:#e0e0dc;
|
||||
color:#9a9a95;
|
||||
font-weight:700;
|
||||
font-family:"Segoe UI","Arial",sans-serif;
|
||||
}
|
||||
.assistant-nom{
|
||||
margin-top:6px;
|
||||
font-weight:700;
|
||||
color:#2a2a2a;
|
||||
font-family:"Segoe UI","Arial",sans-serif;
|
||||
white-space:nowrap;
|
||||
line-height:1.15;
|
||||
}
|
||||
.assistant-fonction{
|
||||
color:#3a3a3a;
|
||||
font-weight:700; /* forcé en gras le 9 septembre 2026 (retour Jean-Marc) : la ligne passait inaperçue sur le fond tasseaux */
|
||||
font-family:"Segoe UI","Arial",sans-serif;
|
||||
white-space:nowrap;
|
||||
line-height:1.15;
|
||||
}
|
||||
/* Panneau "Bureau des assistants" (9 septembre 2026) : même esprit que les
|
||||
cadres photo (liseré blanc, ombre portée) mais fond gris plutôt que
|
||||
blanc — posé une seule fois (pas par agent) dans l'espace qui reste
|
||||
libre sous les 2 dernières colonnes (aujourd'hui Léon et Sophia, voir
|
||||
positionner()), tant qu'il n'y a rien d'autre à y afficher. */
|
||||
.bureau-panneau{
|
||||
position:absolute;
|
||||
box-sizing:border-box;
|
||||
background:#cfcfc9;
|
||||
border-style:solid;
|
||||
border-color:#fff;
|
||||
box-shadow:2px 4px 8px rgba(0,0,0,.35);
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
text-align:center;
|
||||
color:#2a2a2a;
|
||||
font-weight:700;
|
||||
font-family:"Segoe UI","Arial",sans-serif;
|
||||
pointer-events:none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -625,19 +709,24 @@ Créé par Mevelia Solutions">
|
||||
// milieu géométrique — même principe que le 7 septembre). labelCx = centre
|
||||
// du rectangle blanc de l'étiquette, mesuré indépendamment (les 9
|
||||
// rectangles ne sont pas exactement centrés dans leur classeur).
|
||||
// Nouvelle répartition (9 septembre 2026, réflexion stratégique de
|
||||
// Jean-Marc — regroupement plus cohérent des rubriques, ex. Prospection
|
||||
// fusionnée dans Contacts, En-cours+Journalier scindés différemment en
|
||||
// Missions/Propositions/Livraisons/Journalier). Reprend exactement les 9
|
||||
// positions physiques déjà mesurées sur l'avant-plan (x1/x2/labelCx
|
||||
// inchangés, dans l'ordre des classeurs sur la photo) : seuls les
|
||||
// libellés/ids/href changent, aucune nouvelle mesure de pixels nécessaire
|
||||
// tant que l'avant-plan lui-même ne change pas.
|
||||
const CLASSEURS = [
|
||||
{id:'consignes', label:'Consignes', x1:44, x2:83, labelCx:63.5, href:null},
|
||||
{id:'contacts', label:'Contacts', x1:83, x2:120, labelCx:101.0, href:'liste_contacts.html'},
|
||||
{id:'catalogue', label:'Catalogue', x1:120, x2:158, labelCx:138.5, href:null},
|
||||
// "Documentations" (id interne conservé pour l'historique) reste affiché
|
||||
// "Documents", police forcée sur le plafond commun — voir raisonnement
|
||||
// inchangé du 7 septembre 2026 (toujours valable, indépendant de l'image).
|
||||
{id:'documentations', label:'Documents', x1:158, x2:197, labelCx:177.0, href:null},
|
||||
{id:'prospection', label:'Prospection', x1:197, x2:239, labelCx:216.0, href:null},
|
||||
{id:'communication', label:'Réseaux', x1:239, x2:280, labelCx:259.0, href:null},
|
||||
{id:'en-cours', label:'En cours', x1:280, x2:321, labelCx:300.5, href:null},
|
||||
{id:'factures', label:'Factures', x1:321, x2:363, labelCx:341.5, href:null},
|
||||
{id:'journalier', label:'Journalier', x1:363, x2:415, labelCx:383.5, href:null},
|
||||
{id:'catalogue', label:'Catalogue', x1:44, x2:83, labelCx:63.5, href:null},
|
||||
{id:'documents', label:'Documents', x1:83, x2:120, labelCx:101.0, href:null},
|
||||
{id:'contacts', label:'Contacts', x1:120, x2:158, labelCx:138.5, href:'liste_contacts.html'},
|
||||
{id:'missions', label:'Missions', x1:158, x2:197, labelCx:177.0, href:null},
|
||||
{id:'propositions', label:'Propositions', x1:197, x2:239, labelCx:216.0, href:null},
|
||||
{id:'livraisons', label:'Livraisons', x1:239, x2:280, labelCx:259.0, href:null},
|
||||
{id:'factures', label:'Factures', x1:280, x2:321, labelCx:300.5, href:null},
|
||||
{id:'journalier', label:'Journalier', x1:321, x2:363, labelCx:341.5, href:null},
|
||||
{id:'gestion', label:'Gestion', x1:363, x2:415, labelCx:383.5, href:null},
|
||||
];
|
||||
|
||||
// Zone cliquable/survolable du micro et centre de l'icône : remesurés le
|
||||
@@ -666,7 +755,11 @@ Créé par Mevelia Solutions">
|
||||
// Y remesuré le 8 septembre 2026 (soir), même recadrage.
|
||||
// Redescendue un peu le 8 septembre 2026 (soir), retour de Jean-Marc
|
||||
// après 6ᵉ test réel (trop remontée la fois précédente) : 401 → 404.
|
||||
const PASTILLE_CONTACTS_CENTRE_X = 101, PASTILLE_CONTACTS_CENTRE_Y = 404;
|
||||
// X déplacé le 9 septembre 2026 : "Contacts" passe du 2ᵉ au 3ᵉ classeur
|
||||
// dans la nouvelle répartition (voir tableau CLASSEURS) — X reprend le
|
||||
// labelCx du nouvel emplacement (138.5) pour que la pastille reste sous
|
||||
// le bon classeur ; Y inchangé (même hauteur de trou sur les 9 classeurs).
|
||||
const PASTILLE_CONTACTS_CENTRE_X = 138.5, PASTILLE_CONTACTS_CENTRE_Y = 404;
|
||||
const PASTILLE_CONTACTS_DIAM_FRAC = 17 / IMG_W;
|
||||
|
||||
// Zone des post-its personnels (2 septembre 2026, premier affichage réel
|
||||
@@ -709,6 +802,38 @@ Créé par Mevelia Solutions">
|
||||
const FLECHE_PRECEDENTE_CENTRE_X = 962, FLECHE_CENTRE_Y = 410;
|
||||
const FLECHE_SUIVANTE_CENTRE_X = 998;
|
||||
|
||||
// -------- Portraits des assistants, écran 2 (9 septembre 2026) --------
|
||||
// Réglages issus des essais visuels validés par Jean-Marc (voir journal) :
|
||||
// marge réduite au-dessus de la tête, visage recentré, cadrage descendant
|
||||
// sur le buste, taille réduite de 15% par rapport au tout premier essai.
|
||||
// ASSISTANT_PHOTO_RATIO doit rester cohérent avec le recadrage utilisé pour
|
||||
// produire les fichiers assistant_<prenom>.jpg (outillage côté Claude) — à
|
||||
// revoir ensemble si Jean-Marc fournit un jour des photos au format déjà
|
||||
// différent.
|
||||
const ASSISTANT_ZONE_TOP = 14; // marge haute, px de référence (IMG_H)
|
||||
const ASSISTANT_PHOTO_H_MAX = 162; // hauteur max de la photo (hors liseré), px de référence
|
||||
const ASSISTANT_PHOTO_RATIO = 0.657; // largeur / hauteur de la photo
|
||||
const ASSISTANT_MAT = 5; // épaisseur du liseré blanc, px de référence
|
||||
const ASSISTANT_COL_MARGE = 0.85; // fraction de la largeur de colonne réellement utilisable (reste = gouttière)
|
||||
const ASSISTANT_NOM_POLICE_FRAC = 17 / IMG_W;
|
||||
const ASSISTANT_FONCTION_POLICE_FRAC = 12 / IMG_W;
|
||||
|
||||
// Panneau "Bureau des assistants" (9 septembre 2026, retour Jean-Marc) :
|
||||
// posé dans l'espace qui reste libre sous les 2 dernières colonnes de
|
||||
// portraits (aujourd'hui Léon et Sophia), entre le bas du texte des
|
||||
// cartes et le haut du plateau du bureau. BUREAU_PANNEAU_BAS reprend la
|
||||
// même limite que CLASSEURS_Y2/MICRO_ZONE_Y2 plus haut (haut du plateau,
|
||||
// commun à toute la largeur de l'image) avec la même petite marge de
|
||||
// sécurité que ZONE_POSTITS_Y2.
|
||||
const BUREAU_PANNEAU_BAS = 390; // px de référence (IMG_H)
|
||||
const BUREAU_PANNEAU_GAP = 8; // espace entre le texte des cartes et le panneau, px de référence
|
||||
const BUREAU_PANNEAU_POLICE_FRAC = 16 / IMG_W;
|
||||
// Le panneau est un encadré ajusté au texte (mesuré, voir positionner()),
|
||||
// pas une zone qui occupe tout l'espace disponible — cet espace ne sert
|
||||
// qu'à centrer l'encadré (retour Jean-Marc, 9 septembre 2026).
|
||||
const BUREAU_PANNEAU_PAD_H = 16; // marge intérieure horizontale, px de référence
|
||||
const BUREAU_PANNEAU_PAD_V = 10; // marge intérieure verticale, px de référence
|
||||
|
||||
/**
|
||||
* Petit générateur pseudo-aléatoire déterministe (0..1), à partir d'un
|
||||
* entier (TDL_Incr) — pour que le jitter (rotation/décalage) d'un post-it
|
||||
@@ -924,6 +1049,92 @@ Créé par Mevelia Solutions">
|
||||
postit.style.top = (caseTop + (caseH - postitTaille) / 2 + decalageY) + 'px';
|
||||
postit.style.transform = 'rotate(' + rotation.toFixed(1) + 'deg)';
|
||||
});
|
||||
|
||||
// Portraits des assistants (écran 2) : nombre de colonnes = nombre de
|
||||
// cartes réellement créées par creerCartesAssistants() (voir plus bas),
|
||||
// pas de valeur codée en dur — la largeur de colonne se recalcule donc
|
||||
// toute seule si un agent est ajouté ou retiré côté ASP_Agents. scale
|
||||
// convertit un px de référence (IMG_W/IMG_H) en px écran ; identique
|
||||
// dans les deux sens puisque le rectangle "contain" respecte toujours le
|
||||
// ratio IMG_W/IMG_H (voir calcul de dispW/dispH plus haut).
|
||||
const cartesAssistants = coucheAssistants.querySelectorAll('.assistant-carte');
|
||||
if (cartesAssistants.length > 0) {
|
||||
const scale = dispW / IMG_W;
|
||||
const colW = dispW / cartesAssistants.length;
|
||||
const matPx = ASSISTANT_MAT * scale;
|
||||
let photoH = ASSISTANT_PHOTO_H_MAX * scale;
|
||||
// Contrainte de largeur : si la colonne est trop étroite pour la
|
||||
// hauteur visée (beaucoup d'agents), on réduit la photo en proportion
|
||||
// plutôt que de déborder sur la colonne voisine.
|
||||
const largeurMaxCarte = colW * ASSISTANT_COL_MARGE;
|
||||
if (photoH * ASSISTANT_PHOTO_RATIO + 2 * matPx > largeurMaxCarte) {
|
||||
photoH = (largeurMaxCarte - 2 * matPx) / ASSISTANT_PHOTO_RATIO;
|
||||
}
|
||||
const photoW = photoH * ASSISTANT_PHOTO_RATIO;
|
||||
const carteW = photoW + 2 * matPx;
|
||||
const carteH = photoH + 2 * matPx;
|
||||
const topPx = ASSISTANT_ZONE_TOP * scale;
|
||||
const nomPx = ASSISTANT_NOM_POLICE_FRAC * dispW;
|
||||
const fonctionPx = ASSISTANT_FONCTION_POLICE_FRAC * dispW;
|
||||
|
||||
cartesAssistants.forEach(function (carte, index) {
|
||||
const cx = colW * index + colW / 2;
|
||||
carte.style.left = (cx - carteW / 2) + 'px';
|
||||
carte.style.top = topPx + 'px';
|
||||
carte.style.width = carteW + 'px';
|
||||
const cadre = carte.querySelector('.assistant-cadre');
|
||||
cadre.style.width = carteW + 'px';
|
||||
cadre.style.height = carteH + 'px';
|
||||
cadre.style.padding = matPx + 'px';
|
||||
const nomEl = carte.querySelector('.assistant-nom');
|
||||
if (nomEl) nomEl.style.fontSize = nomPx + 'px';
|
||||
const fonctionEl = carte.querySelector('.assistant-fonction');
|
||||
if (fonctionEl) fonctionEl.style.fontSize = fonctionPx + 'px';
|
||||
const repli = carte.querySelector('.assistant-photo-repli');
|
||||
if (repli) repli.style.fontSize = (photoH * 0.3) + 'px';
|
||||
});
|
||||
|
||||
// Panneau "Bureau des assistants" : la zone sous les 2 dernières
|
||||
// colonnes (aujourd'hui Léon et Sophia) ne sert qu'à CENTRER
|
||||
// l'encadré — l'encadré lui-même est ajusté au texte (mesuré via
|
||||
// ctxMesure, voir plus haut), pas étiré sur toute la zone (retour
|
||||
// Jean-Marc, 9 septembre 2026). Bas du texte des cartes calculé
|
||||
// analytiquement (pas mesuré en DOM) : coucheAssistants peut être
|
||||
// parquée hors document (fond non affiché), où
|
||||
// offsetHeight/getBoundingClientRect renverraient 0.
|
||||
if (cartesAssistants.length >= 2) {
|
||||
const nomLigne = nomPx * 1.15; // line-height:1.15, voir .assistant-nom
|
||||
const nomMargeHaut = 6 * scale; // margin-top:6px, voir .assistant-nom
|
||||
const fonctionLigne = fonctionPx * 1.15; // line-height:1.15, voir .assistant-fonction
|
||||
const basCarte = topPx + carteH + nomMargeHaut + nomLigne + fonctionLigne;
|
||||
const zoneTop = basCarte + BUREAU_PANNEAU_GAP * scale;
|
||||
const zoneBas = BUREAU_PANNEAU_BAS * scale;
|
||||
const zoneGauche = colW * (cartesAssistants.length - 2);
|
||||
const zoneLargeur = colW * 2;
|
||||
const zoneCentreX = zoneGauche + zoneLargeur / 2;
|
||||
const zoneCentreY = zoneTop + (zoneBas - zoneTop) / 2;
|
||||
|
||||
const panneauPolicePx = BUREAU_PANNEAU_POLICE_FRAC * dispW;
|
||||
ctxMesure.font = '700 ' + panneauPolicePx + 'px "Segoe UI","Arial",sans-serif';
|
||||
const texteLargeur = ctxMesure.measureText(panneauBureau.textContent).width;
|
||||
const padH = BUREAU_PANNEAU_PAD_H * scale;
|
||||
const padV = BUREAU_PANNEAU_PAD_V * scale;
|
||||
const panneauLargeur = texteLargeur + 2 * padH;
|
||||
const panneauHauteur = panneauPolicePx * 1.15 + 2 * padV;
|
||||
|
||||
panneauBureau.style.display = 'flex';
|
||||
panneauBureau.style.left = (zoneCentreX - panneauLargeur / 2) + 'px';
|
||||
panneauBureau.style.top = (zoneCentreY - panneauHauteur / 2) + 'px';
|
||||
panneauBureau.style.width = panneauLargeur + 'px';
|
||||
panneauBureau.style.height = panneauHauteur + 'px';
|
||||
panneauBureau.style.borderWidth = matPx + 'px';
|
||||
panneauBureau.style.fontSize = panneauPolicePx + 'px';
|
||||
} else {
|
||||
panneauBureau.style.display = 'none';
|
||||
}
|
||||
} else {
|
||||
panneauBureau.style.display = 'none';
|
||||
}
|
||||
}
|
||||
// -------- Fonds interchangeables (8 septembre 2026) --------
|
||||
// 3 fonds codés en dur (décision de Jean-Marc, pas de liste extensible
|
||||
@@ -948,16 +1159,36 @@ Créé par Mevelia Solutions">
|
||||
const couchePostits = document.createElement('div');
|
||||
couchePostits.id = 'postits-layer';
|
||||
|
||||
// Portraits des assistants (écran 2, 9 septembre 2026) : même principe que
|
||||
// couchePostits ci-dessus — un noeud créé une seule fois, rempli de façon
|
||||
// asynchrone par chargerAgentsEcranAssistants() plus bas, déplacé (jamais
|
||||
// dupliqué) entre les slides par creerFondSlide().
|
||||
const coucheAssistants = document.createElement('div');
|
||||
coucheAssistants.id = 'assistants-layer';
|
||||
|
||||
// Panneau "Bureau des assistants" (voir commentaire CSS .bureau-panneau et
|
||||
// constantes BUREAU_PANNEAU_* plus haut) : contenu statique, créé une
|
||||
// seule fois ici et jamais recréé par creerCartesAssistants() (qui ne
|
||||
// touche qu'aux .assistant-carte) — seule sa position/taille est
|
||||
// recalculée à chaque appel de positionner().
|
||||
const panneauBureau = document.createElement('div');
|
||||
panneauBureau.className = 'bureau-panneau';
|
||||
panneauBureau.textContent = 'Bureau des assistants';
|
||||
coucheAssistants.appendChild(panneauBureau);
|
||||
|
||||
function creerFondSlide(index) {
|
||||
const slide = document.createElement('div');
|
||||
slide.className = 'fond-slide';
|
||||
slide.style.backgroundImage = "url('" + FONDS[index] + "')";
|
||||
// Le fond liège (index 0) embarque la couche des post-its : un simple
|
||||
// appendChild déplace le noeud existant (le retire au passage de son
|
||||
// ancien parent, s'il en avait un) — pas de duplication, pas de perte du
|
||||
// contenu déjà chargé par chargerMesPostits().
|
||||
// Le fond liège (index 0) embarque la couche des post-its, le fond
|
||||
// tasseaux gris (index 1, écran assistants) la couche des portraits : un
|
||||
// simple appendChild déplace le noeud existant (le retire au passage de
|
||||
// son ancien parent, s'il en avait un) — pas de duplication, pas de perte
|
||||
// du contenu déjà chargé.
|
||||
if (index === 0) {
|
||||
slide.appendChild(couchePostits);
|
||||
} else if (index === 1) {
|
||||
slide.appendChild(coucheAssistants);
|
||||
}
|
||||
return slide;
|
||||
}
|
||||
@@ -1151,6 +1382,70 @@ Créé par Mevelia Solutions">
|
||||
}
|
||||
chargerMesPostits();
|
||||
|
||||
// Portraits des assistants, écran 2 (9 septembre 2026 — voir journal et
|
||||
// réflexions stratégiques). Source : agents.php, qui sert déjà
|
||||
// AGN_Prenom/AGN_Fonction pour le pilotage vocal — AGN_Photo (nom de
|
||||
// fichier, ex. "assistant_matilda.jpg") et le tri par AGN_OrdreAffichage
|
||||
// s'y ajoutent pour cet écran (voir commentaire d'en-tête de agents.php). Un agent sans
|
||||
// AGN_Photo reste affiché (repli visuel "?", voir .assistant-photo-repli) :
|
||||
// jamais de colonne manquante silencieusement. Nombre de colonnes non codé
|
||||
// en dur : une carte par agent réellement renvoyé (voir positionner()).
|
||||
function creerCartesAssistants() {
|
||||
// Ne retire que les cartes (pas le panneau "Bureau des assistants",
|
||||
// ajouté une seule fois à la création de coucheAssistants — voir
|
||||
// panneauBureau plus haut).
|
||||
coucheAssistants.querySelectorAll('.assistant-carte').forEach(function (el) { el.remove(); });
|
||||
(agentsEcranAssistants || []).forEach(function (agent) {
|
||||
const carte = document.createElement('div');
|
||||
carte.className = 'assistant-carte';
|
||||
|
||||
const cadre = document.createElement('div');
|
||||
cadre.className = 'assistant-cadre';
|
||||
if (agent.AGN_Photo) {
|
||||
const img = document.createElement('img');
|
||||
img.className = 'assistant-photo';
|
||||
img.alt = agent.AGN_Prenom || '';
|
||||
img.src = agent.AGN_Photo;
|
||||
cadre.appendChild(img);
|
||||
} else {
|
||||
const repli = document.createElement('div');
|
||||
repli.className = 'assistant-photo-repli';
|
||||
repli.textContent = '?';
|
||||
cadre.appendChild(repli);
|
||||
}
|
||||
carte.appendChild(cadre);
|
||||
|
||||
const nom = document.createElement('div');
|
||||
nom.className = 'assistant-nom';
|
||||
nom.textContent = agent.AGN_Prenom || '';
|
||||
carte.appendChild(nom);
|
||||
|
||||
if (agent.AGN_Fonction) {
|
||||
const fonction = document.createElement('div');
|
||||
fonction.className = 'assistant-fonction';
|
||||
fonction.textContent = agent.AGN_Fonction;
|
||||
carte.appendChild(fonction);
|
||||
}
|
||||
|
||||
coucheAssistants.appendChild(carte);
|
||||
});
|
||||
positionner(); // place les cartes qui viennent d'être (re)créées
|
||||
}
|
||||
|
||||
let agentsEcranAssistants = [];
|
||||
async function chargerAgentsEcranAssistants() {
|
||||
try {
|
||||
const reponse = await fetch('agents.php');
|
||||
if (!reponse.ok) throw new Error('HTTP ' + reponse.status);
|
||||
const data = await reponse.json();
|
||||
agentsEcranAssistants = data.agents || [];
|
||||
creerCartesAssistants();
|
||||
} catch (erreur) {
|
||||
console.error('Erreur de chargement de agents.php (écran assistants) :', erreur);
|
||||
}
|
||||
}
|
||||
chargerAgentsEcranAssistants();
|
||||
|
||||
// Lien visible "→ Liste des tâches" retiré le 2 septembre 2026 à la
|
||||
// demande de Jean-Marc. Échap avait été conservé ce soir-là comme
|
||||
// échappatoire silencieuse vers liste_todolist.html, pour ne pas rester
|
||||
|
||||
Reference in New Issue
Block a user