/** * Pages profil / utilisateur (profile.php, user-edit.php, user-new.php) : * réordonnancement des sections natives, popovers d'aide, mode visuel forcé * sur les WYSIWYG Pods. * Dépend de admin-base.js (window.ThalimAdmin) — enqueue conditionnel. */ (function($) { 'use strict'; var TA = window.ThalimAdmin; var safeRun = TA.safeRun; // Only native WP field sections — never touch Pods tables (they may contain TinyMCE editors) var PROFILE_SECTION_KEYS = [ 'user-language-wrap', 'user-first-name-wrap', 'user-email-wrap', 'user-pass1-wrap', 'upload-avatar-row', ]; // Desired order. Groups of 2 are wrapped in a flex row and displayed side by side. var PROFILE_ORDER = [ ['user-first-name-wrap', 'upload-avatar-row'], ['user-email-wrap'], ['user-language-wrap', 'user-pass1-wrap'], ]; function reorderProfileSections() { var form = TA.getProfileForm(); if (!form) return; var pairMap = {}; form.querySelectorAll('table.form-table').forEach(function(table) { PROFILE_SECTION_KEYS.forEach(function(key) { if (pairMap[key] || !table.querySelector('.' + key)) return; // Find the associated heading: first try preceding sibling in same parent, // then look for an h2/h3 inside the same wrapper element. var h2 = null; var el = table.previousElementSibling; while (el) { if (el.tagName === 'H2' || el.tagName === 'H3') { h2 = el; break; } if (el.tagName === 'TABLE') break; el = el.previousElementSibling; } if (!h2 && table.parentElement !== form) { h2 = table.parentElement.querySelector('h2, h3'); } // The unit to move: if h2 and table share a non-form wrapper, move the wrapper. var wrapper = null; if (h2 && h2.parentElement !== form && h2.parentElement === table.parentElement) { wrapper = h2.parentElement; } pairMap[key] = { h2: h2, table: table, wrapper: wrapper }; }); }); // Remove all matched units from DOM (dedup by actual element) var removed = new Set(); function removeEl(el) { if (el && !removed.has(el)) { removed.add(el); el.remove(); } } Object.values(pairMap).forEach(function(unit) { if (unit.wrapper) { removeEl(unit.wrapper); } else { removeEl(unit.h2); removeEl(unit.table); } }); // Re-insert in declared order before the submit button var submitAnchor = form.querySelector('p.submit'); function append(el) { if (submitAnchor && submitAnchor.parentNode) form.insertBefore(el, submitAnchor); else form.appendChild(el); } function appendUnit(unit) { if (unit.wrapper) { append(unit.wrapper); } else { if (unit.h2) append(unit.h2); append(unit.table); } } PROFILE_ORDER.forEach(function(group) { var available = group.filter(function(key) { return !!pairMap[key]; }); if (!available.length) return; // Dedup: two keys may resolve to the same table/wrapper var seen = new Set(); var units = []; available.forEach(function(key) { var unit = pairMap[key]; var id = unit.wrapper || unit.table; if (!seen.has(id)) { seen.add(id); units.push(unit); } }); if (units.length === 1) { appendUnit(units[0]); } else { var row = document.createElement('div'); row.className = 'profile-section-row'; units.forEach(function(unit) { var col = document.createElement('div'); col.className = 'profile-section-col'; if (unit.wrapper) { col.appendChild(unit.wrapper); } else { if (unit.h2) col.appendChild(unit.h2); col.appendChild(unit.table); } row.appendChild(col); }); append(row); } }); } // Regroupe les axes thématiques par période (champ en cases à cocher, comme // la page post — implémentation partagée dans admin-base.js). Les checkboxes // sont rendues par le DFV React de façon asynchrone ; sur user-new.php, la // page est très lourde (beaucoup de champs Pods) et le rendu peut arriver // bien après le chargement. On observe donc le formulaire jusqu'à ce que les // cases apparaissent, plutôt qu'un retry borné qui expirait sur user-new. function groupProfileAxes() { function tryGroup() { var row = document.querySelector('.' + TA.CONFIG.rows.axes); var list = row && row.querySelector('ul'); if (!list) return false; if (list.querySelector('.axes-group-label')) return true; // déjà groupé if (!list.querySelector('input[type="checkbox"]')) return false; // pas encore rendu TA.groupAxesCheckboxes(); return true; } if (tryGroup()) return; // On observe la LIGNE du champ (le