ui(ucp): v2.6.3 onglets dynamiques par groupe dans l'Annuaire de l'Entreprise

This commit is contained in:
sorcier committed 2026-11-12 02:42:13 +01:00
1 parent 745e9307d7
commit 8cb8f1cdf7
3 files changed
+67 -2

No files matched your search

+63 -1
View File
@@ -9,6 +9,7 @@ let ucpState = {
selectedVmExt: '',
vmFolderFilter: 'all',
phonebook: [],
selectedPbGroup: '__all__',
activeTab: 'extensions',
};
@@ -755,12 +756,73 @@ async function loadPhonebook() {
}
}
function renderPhonebookGroupTabs(allContacts) {
const tabsEl = document.getElementById('ucp-pb-group-tabs');
if (!tabsEl) return;
const counts = {};
for (const c of allContacts) {
const grp = String(c.group_name || '').trim() || 'Général';
counts[grp] = (counts[grp] || 0) + 1;
}
const groups = Object.keys(counts).sort((a, b) => {
if (a === 'Général') return -1;
if (b === 'Général') return 1;
return a.localeCompare(b, 'fr', { sensitivity: 'base' });
});
if (ucpState.selectedPbGroup !== '__all__' && !counts[ucpState.selectedPbGroup]) {
ucpState.selectedPbGroup = '__all__';
}
if (groups.length <= 1 && allContacts.length === 0) {
tabsEl.innerHTML = '';
return;
}
const renderPill = (key, label, count) => {
const isActive = ucpState.selectedPbGroup === key;
const btnCls = isActive
? 'bg-indigo-600 text-white border-indigo-600 shadow-sm'
: 'bg-white hover:bg-slate-50 text-slate-600 border-slate-200 hover:border-slate-300';
const badgeCls = isActive
? 'bg-white/20 text-white'
: 'bg-slate-100 text-slate-600';
return `
<button type="button" data-pb-group="${escapeHtml(key)}"
class="ucp-pb-group-btn inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border text-xs font-semibold transition ${btnCls}">
<span>${escapeHtml(label)}</span>
<span class="px-1.5 py-0.2 rounded-full text-[10px] font-bold ${badgeCls}">${count}</span>
</button>
`;
};
tabsEl.innerHTML = [
renderPill('__all__', 'Tous', allContacts.length),
...groups.map(g => renderPill(g, g, counts[g])),
].join('');
tabsEl.querySelectorAll('.ucp-pb-group-btn').forEach(btn => {
btn.addEventListener('click', () => {
ucpState.selectedPbGroup = btn.getAttribute('data-pb-group') || '__all__';
renderPhonebookGrid();
});
});
}
function renderPhonebookGrid() {
const grid = document.getElementById('ucp-pb-grid');
if (!grid) return;
const allContacts = ucpState.phonebook || [];
renderPhonebookGroupTabs(allContacts);
const activeGroup = ucpState.selectedPbGroup || '__all__';
const q = (document.getElementById('ucp-pb-search')?.value || '').trim().toLowerCase();
const list = (ucpState.phonebook || []).filter(c => {
const list = allContacts.filter(c => {
const grp = String(c.group_name || '').trim() || 'Général';
if (activeGroup !== '__all__' && grp !== activeGroup) return false;
if (!q) return true;
return [c.display_name, c.internal_number, c.mobile_number, c.other_number, c.email, c.group_name]
.some(v => String(v || '').toLowerCase().includes(q));
+2
View File
@@ -388,6 +388,8 @@ $csrfToken = UcpAuth::getCsrfToken();
class="w-full sm:w-72 px-3.5 py-2 rounded-xl bg-white border border-slate-300 text-xs text-slate-900 focus:ring-2 focus:ring-indigo-500/30 focus:border-indigo-500 focus:outline-none">
</div>
<div id="ucp-pb-group-tabs" class="flex flex-wrap items-center gap-2"></div>
<div id="ucp-pb-grid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="ucp-card rounded-2xl p-8 text-center text-sm text-slate-400 col-span-full">Chargement de l'annuaire…</div>
</div>