fix(calendar): reactive update of daily team members in calendar grid
This commit is contained in:
parent
fdc315788f
commit
41898f211f
1 changed files with 86 additions and 6 deletions
|
|
@ -4998,11 +4998,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
const viewMode = filterViewModeSelect?.value || 'timeline';
|
const viewMode = filterViewModeSelect?.value || 'timeline';
|
||||||
const targetDate = customDate || (viewMode === 'teams_daily' ? formatDateISO(teamsDailyActiveDate) : null);
|
const targetDate = customDate || (viewMode === 'teams_daily' ? formatDateISO(teamsDailyActiveDate) : null);
|
||||||
|
|
||||||
if (targetDate) {
|
|
||||||
const urlObj = new URL(url, window.location.origin);
|
const urlObj = new URL(url, window.location.origin);
|
||||||
urlObj.searchParams.set('date', targetDate);
|
if (viewMode) {
|
||||||
url = urlObj.pathname + urlObj.search;
|
urlObj.searchParams.set('view_mode', viewMode);
|
||||||
}
|
}
|
||||||
|
if (targetDate) {
|
||||||
|
urlObj.searchParams.set('date', targetDate);
|
||||||
|
}
|
||||||
|
url = urlObj.pathname + urlObj.search;
|
||||||
|
|
||||||
return fetch(url, { cache: 'no-store' })
|
return fetch(url, { cache: 'no-store' })
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
|
|
@ -5028,6 +5031,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.loadCalendarData = loadCalendarData;
|
||||||
|
window.getTeamColor = getTeamColor;
|
||||||
|
|
||||||
// Reset filters handler
|
// Reset filters handler
|
||||||
const resetFiltersBtn = document.getElementById('reset-filters');
|
const resetFiltersBtn = document.getElementById('reset-filters');
|
||||||
if (resetFiltersBtn) {
|
if (resetFiltersBtn) {
|
||||||
|
|
@ -5314,6 +5320,63 @@ function openTeamDailyMembersModal(teamId, dateStr, teamName) {
|
||||||
loadTeamDailyMembersModalData(teamId, dateStr);
|
loadTeamDailyMembersModalData(teamId, dateStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateTeamsDailyGridCell(teamId, dateStr, currentMembers, teamObj) {
|
||||||
|
if (!teamId || !dateStr) return;
|
||||||
|
const cell = document.querySelector(`.teams-daily-grid-cell[data-team-id="${teamId}"][data-date="${dateStr}"]`);
|
||||||
|
if (!cell) return;
|
||||||
|
|
||||||
|
let membersContainer = cell.querySelector('.team-members-list');
|
||||||
|
const teamColor = typeof getTeamColor === 'function' ? getTeamColor(teamId) : (window.getTeamColor ? window.getTeamColor(teamId) : '#0d6efd');
|
||||||
|
const canEditThisTeam = (typeof canEditTeams !== 'undefined' && Boolean(canEditTeams)) && (!teamObj || teamObj.can_edit !== false);
|
||||||
|
const todayStr = new Date().toISOString().split('T')[0];
|
||||||
|
const isPastDay = dateStr < todayStr;
|
||||||
|
const titleTooltip = canEditThisTeam && !isPastDay ? gettext('Modifier la composition de l’équipe pour ce jour') : gettext('Composition de l’équipe');
|
||||||
|
const teamName = teamObj && teamObj.name ? teamObj.name : '';
|
||||||
|
|
||||||
|
if (!membersContainer) {
|
||||||
|
membersContainer = document.createElement('div');
|
||||||
|
cell.prepend(membersContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
membersContainer.setAttribute('data-team-id', teamId);
|
||||||
|
membersContainer.setAttribute('data-date', dateStr);
|
||||||
|
if (teamName) {
|
||||||
|
membersContainer.setAttribute('data-team-name', teamName);
|
||||||
|
}
|
||||||
|
membersContainer.setAttribute('title', titleTooltip);
|
||||||
|
|
||||||
|
if (currentMembers && currentMembers.length > 0) {
|
||||||
|
const formattedMembers = currentMembers.map(m => {
|
||||||
|
const name = typeof m === 'object' && m ? m.name : m;
|
||||||
|
const isAbsent = typeof m === 'object' && m ? Boolean(m.is_absent) : false;
|
||||||
|
const absenceReason = typeof m === 'object' && m ? (m.absence_reason || '') : '';
|
||||||
|
const isMultiTeam = typeof m === 'object' && m ? Boolean(m.is_multi_team) : false;
|
||||||
|
const otherTeams = typeof m === 'object' && m && m.other_teams ? m.other_teams : [];
|
||||||
|
|
||||||
|
let memberNameHtml = escapeHtml(name);
|
||||||
|
if (isMultiTeam) {
|
||||||
|
const otherNames = otherTeams.map(t => t.name).join(', ');
|
||||||
|
const tooltip = otherNames ? `${gettext('Planifié aussi dans')} : ${otherNames}` : gettext('Planifié dans plusieurs équipes ce jour');
|
||||||
|
memberNameHtml += ` <i class="bi bi-diagram-3 text-warning ms-1" style="font-size:0.75rem;" title="${escapeHtml(tooltip)}"></i>`;
|
||||||
|
}
|
||||||
|
if (isAbsent) {
|
||||||
|
return `<span class="text-decoration-line-through text-danger opacity-75" title="${escapeHtml(absenceReason || gettext('Absent'))}">${memberNameHtml}</span> <span class="badge text-bg-danger p-0 px-1 font-monospace" style="font-size:0.6rem;">${escapeHtml(absenceReason || gettext('Absent'))}</span>`;
|
||||||
|
}
|
||||||
|
return memberNameHtml;
|
||||||
|
}).join(', ');
|
||||||
|
|
||||||
|
membersContainer.className = 'team-members-list clickable-team-members text-muted small fst-italic mb-2';
|
||||||
|
membersContainer.style.borderLeft = `3px solid ${teamColor}`;
|
||||||
|
membersContainer.style.cursor = 'pointer';
|
||||||
|
membersContainer.innerHTML = `<i class="bi bi-people-fill me-1" style="color: ${teamColor};"></i>${formattedMembers}`;
|
||||||
|
} else {
|
||||||
|
membersContainer.className = 'team-members-list clickable-team-members text-muted small fst-italic mb-2 text-opacity-50';
|
||||||
|
membersContainer.style.borderLeft = '3px solid #cbd5e1';
|
||||||
|
membersContainer.style.cursor = 'pointer';
|
||||||
|
membersContainer.innerHTML = `<i class="bi bi-people me-1"></i>(${gettext('Aucun membre')})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function loadTeamDailyMembersModalData(teamId, dateStr) {
|
function loadTeamDailyMembersModalData(teamId, dateStr) {
|
||||||
const spinner = document.getElementById('team-daily-modal-spinner');
|
const spinner = document.getElementById('team-daily-modal-spinner');
|
||||||
const content = document.getElementById('team-daily-modal-content');
|
const content = document.getElementById('team-daily-modal-content');
|
||||||
|
|
@ -5367,6 +5430,11 @@ function loadTeamDailyMembersModalData(teamId, dateStr) {
|
||||||
else readonlyAlert.classList.add('d-none');
|
else readonlyAlert.classList.add('d-none');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update calendar cell immediately if present in the teams daily grid
|
||||||
|
if (data.current_members) {
|
||||||
|
updateTeamsDailyGridCell(teamId, dateStr, data.current_members, data.team);
|
||||||
|
}
|
||||||
|
|
||||||
// Render current members
|
// Render current members
|
||||||
const members = data.current_members || [];
|
const members = data.current_members || [];
|
||||||
if (membersCountEl) membersCountEl.textContent = members.length;
|
if (membersCountEl) membersCountEl.textContent = members.length;
|
||||||
|
|
@ -5497,8 +5565,10 @@ function assignMemberToDailyTeam(memberId, teamId, dateStr, action) {
|
||||||
setTimeout(() => { if (succAlert) succAlert.classList.add('d-none'); }, 3000);
|
setTimeout(() => { if (succAlert) succAlert.classList.add('d-none'); }, 3000);
|
||||||
}
|
}
|
||||||
loadTeamDailyMembersModalData(teamId, dateStr);
|
loadTeamDailyMembersModalData(teamId, dateStr);
|
||||||
if (typeof loadCalendarData === 'function') {
|
if (typeof window.loadCalendarData === 'function') {
|
||||||
loadCalendarData();
|
window.loadCalendarData(dateStr);
|
||||||
|
} else if (typeof loadCalendarData === 'function') {
|
||||||
|
loadCalendarData(dateStr);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
@ -5560,3 +5630,13 @@ if (_memberHistoryModalEl) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _teamDailyMembersModalEl = document.getElementById('teamDailyMembersModal');
|
||||||
|
if (_teamDailyMembersModalEl) {
|
||||||
|
_teamDailyMembersModalEl.addEventListener('hidden.bs.modal', function () {
|
||||||
|
if (typeof window.loadCalendarData === 'function') {
|
||||||
|
window.loadCalendarData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue