chore: update internationalization translation files and model reference locations

This commit is contained in:
kdeterme 2026-09-02 12:09:55 +02:00
parent 28696e7339
commit da7de1ac7d
7 changed files with 1769 additions and 771 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -279,6 +279,35 @@
background: #fcfcfc;
}
/* Bouton de duplication rapide au bas à droite des en-têtes de jour */
.btn-quick-duplicate {
position: absolute;
bottom: 4px;
right: 4px;
width: 24px;
height: 24px;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 4px;
background: #ffffff;
border: 1px solid #cbd5e1;
color: #0d6efd;
box-shadow: 0 1px 2px rgba(0,0,0,0.06);
cursor: pointer;
transition: all 0.15s ease;
z-index: 5;
}
.btn-quick-duplicate:hover {
background: #0d6efd;
border-color: #0d6efd;
color: #ffffff;
box-shadow: 0 2px 5px rgba(13,110,253,0.3);
transform: scale(1.1);
}
/* Jours passés grisés */
.planning-table th.is-past-header {
background: #e9ecef;
@ -1525,25 +1554,36 @@ function renderPlanningMatrix(data) {
if (day.is_past) headerClasses.push('is-past-header');
th.className = headerClasses.join(' ');
const quickDupTitle = "{% trans 'Dupliquer vers le jour suivant (avec absences)'|escapejs %}";
const optionsTitle = "{% trans 'Options de la journée'|escapejs %}";
const dupCustomTitle = "{% trans 'Dupliquer cette journée…'|escapejs %}";
th.innerHTML = `
<div class="d-flex justify-content-between align-items-center">
<div class="flex-grow-1 text-center">
<div class="small text-uppercase ${day.is_past ? 'text-muted opacity-75' : 'text-muted'}" style="font-size:0.75rem;">${escapeHtml(day.day_short)}</div>
<div class="fw-bold fs-6 ${day.is_past ? 'text-muted' : ''}">${escapeHtml(day.day_num)}</div>
${day.is_today ? `<span class="badge bg-primary text-white mt-1" style="font-size:0.65rem;">{% trans "Aujourd'hui"|escapejs %}</span>` : ''}
${day.is_past ? `<span class="badge bg-light text-muted border mt-1" style="font-size:0.62rem;"><i class="bi bi-clock-history me-1"></i>{% trans "Passé"|escapejs %}</span>` : ''}
</div>
<div class="d-flex flex-column align-items-center justify-content-center position-relative py-1" style="min-height: 56px;">
${CAN_EDIT_TEAMS ? `
<div class="dropdown">
<button class="btn btn-sm btn-link text-muted p-0 dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" title="{% trans 'Options de la journée'|escapejs %}"></button>
<div class="dropdown position-absolute" style="top: 0px; right: 0px;">
<button class="btn btn-sm btn-link text-muted p-0 dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" title="${optionsTitle}"></button>
<ul class="dropdown-menu dropdown-menu-end shadow-sm">
<li>
<a class="dropdown-item small" href="javascript:void(0)" onclick="openDuplicateModalForDay('${day.date}')">
<i class="bi bi-copy me-2 text-primary"></i>{% trans "Dupliquer cette journée…"|escapejs %}
<i class="bi bi-copy me-2 text-primary"></i>${dupCustomTitle}
</a>
</li>
</ul>
</div>` : ''}
<div class="small text-uppercase ${day.is_past ? 'text-muted opacity-75' : 'text-muted'}" style="font-size:0.75rem; letter-spacing: 0.5px;">${escapeHtml(day.day_short)}</div>
<div class="fw-bold fs-6 ${day.is_past ? 'text-muted' : ''}">${escapeHtml(day.day_num)}</div>
${day.is_today ? `<span class="badge bg-primary text-white mt-1" style="font-size:0.65rem;">{% trans "Aujourd'hui"|escapejs %}</span>` : ''}
${day.is_past ? `<span class="badge bg-light text-muted border mt-1" style="font-size:0.62rem;"><i class="bi bi-clock-history me-1"></i>{% trans "Passé"|escapejs %}</span>` : ''}
${CAN_EDIT_TEAMS ? `
<button type="button"
class="btn-quick-duplicate"
title="${quickDupTitle}"
onclick="quickDuplicateToNextDay('${day.date}')">
<i class="bi bi-chevron-double-right"></i>
</button>` : ''}
</div>
`;
theadRow.appendChild(th);
@ -1887,6 +1927,36 @@ function openDuplicateModalForDay(dateStr) {
$('#dupTargetDate').val(d.toISOString().split('T')[0]);
}
function quickDuplicateToNextDay(sourceDateStr) {
const parts = sourceDateStr.split('-');
const srcYear = parseInt(parts[0], 10);
const srcMonth = parseInt(parts[1], 10) - 1;
const srcDay = parseInt(parts[2], 10);
const d = new Date(srcYear, srcMonth, srcDay);
d.setDate(d.getDate() + 1);
const nextYear = d.getFullYear();
const nextMonth = String(d.getMonth() + 1).padStart(2, '0');
const nextDay = String(d.getDate()).padStart(2, '0');
const targetDateStr = `${nextYear}-${nextMonth}-${nextDay}`;
postJSON(
'/contracts/teams/planning/duplicate/',
{
mode: 'day',
source_date: sourceDateStr,
target_date: targetDateStr,
copy_absences: true,
},
function(resp) {
loadPlanningData();
},
function(err) {
alert(err);
}
);
}
function submitDuplicatePlanning() {
const mode = $('input[name="dupMode"]:checked').val();
const sourceDate = mode === 'week' ? $('#dupSourceWeek').val() : $('#dupSourceDate').val();