Umstellung auf anzeige x h y min
This commit is contained in:
@@ -52,11 +52,11 @@
|
||||
<div class="summary">
|
||||
<div class="summary-item">
|
||||
<strong>Gesamtstunden diese Woche:</strong>
|
||||
<span id="totalHours">0.00 h</span>
|
||||
<span id="totalHours">0 h 0 min</span>
|
||||
</div>
|
||||
<div class="summary-item" id="overtimeSummaryItem" style="display: none;">
|
||||
<strong>Überstunden diese Woche:</strong>
|
||||
<span id="overtimeHours">0.00 h</span>
|
||||
<span id="overtimeHours">0 h 0 min</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/format-hours.js"></script>
|
||||
<script src="/js/dashboard.js"></script>
|
||||
<script>
|
||||
// Wochenende-Sektion ein-/ausklappen
|
||||
|
||||
@@ -187,6 +187,7 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script src="/js/format-hours.js"></script>
|
||||
<script>
|
||||
// Rollenwechsel
|
||||
const roleSwitcher = document.getElementById('roleSwitcher');
|
||||
@@ -231,15 +232,7 @@
|
||||
return new Date(s.replace(' ', 'T') + 'Z');
|
||||
}
|
||||
|
||||
function formatHours(value) {
|
||||
const n = Number(value);
|
||||
if (!Number.isFinite(n)) return '';
|
||||
const sign = n > 0 ? '+' : '';
|
||||
let s = sign + n.toFixed(2);
|
||||
s = s.replace(/\.00$/, '');
|
||||
s = s.replace(/(\.\d)0$/, '$1');
|
||||
return s;
|
||||
}
|
||||
// formatHoursMin aus format-hours.js (window.formatHoursMin)
|
||||
|
||||
let correctionsExpanded = false;
|
||||
function toggleCorrectionsSection() {
|
||||
@@ -286,18 +279,18 @@
|
||||
// Zusammenfassung anzeigen
|
||||
const totalOvertimeEl = document.getElementById('totalOvertime');
|
||||
totalOvertimeEl.textContent =
|
||||
(totalOvertime >= 0 ? '+' : '') + totalOvertime.toFixed(2) + ' h';
|
||||
(totalOvertime >= 0 ? '+' : '') + formatHoursMin(totalOvertime);
|
||||
totalOvertimeEl.className =
|
||||
'summary-value ' + (totalOvertime >= 0 ? 'overtime-positive' : 'overtime-negative');
|
||||
|
||||
const totalOvertimeTakenEl = document.getElementById('totalOvertimeTaken');
|
||||
totalOvertimeTakenEl.textContent =
|
||||
totalOvertimeTaken.toFixed(2) + ' h';
|
||||
formatHoursMin(totalOvertimeTaken);
|
||||
totalOvertimeTakenEl.className = 'summary-value overtime-positive';
|
||||
|
||||
const remainingOvertimeEl = document.getElementById('remainingOvertime');
|
||||
remainingOvertimeEl.textContent =
|
||||
(remainingOvertime >= 0 ? '+' : '') + remainingOvertime.toFixed(2) + ' h';
|
||||
(remainingOvertime >= 0 ? '+' : '') + formatHoursMin(remainingOvertime);
|
||||
remainingOvertimeEl.className =
|
||||
'summary-value ' + (remainingOvertime >= 0 ? 'overtime-positive' : 'overtime-negative');
|
||||
|
||||
@@ -305,7 +298,7 @@
|
||||
const offsetItem = document.getElementById('offsetItem');
|
||||
const offsetValue = document.getElementById('overtimeOffset');
|
||||
if (overtimeOffset !== 0) {
|
||||
offsetValue.textContent = (overtimeOffset >= 0 ? '+' : '') + overtimeOffset.toFixed(2) + ' h';
|
||||
offsetValue.textContent = (overtimeOffset >= 0 ? '+' : '') + formatHoursMin(overtimeOffset);
|
||||
offsetValue.className = 'summary-value ' + (overtimeOffset >= 0 ? 'overtime-positive' : 'overtime-negative');
|
||||
offsetItem.style.display = 'flex';
|
||||
} else {
|
||||
@@ -327,12 +320,12 @@
|
||||
corrections.forEach(c => {
|
||||
const dt = parseSqliteDatetime(c.corrected_at);
|
||||
const dateText = dt ? dt.toLocaleDateString('de-DE') : '';
|
||||
const hoursText = formatHours(c.correction_hours);
|
||||
const hoursText = formatHoursMin(c.correction_hours);
|
||||
const reason = (c && c.reason != null) ? String(c.reason).trim() : '';
|
||||
const li = document.createElement('li');
|
||||
li.textContent = reason
|
||||
? `Korrektur am ${dateText} ${hoursText} h – ${reason}`
|
||||
: `Korrektur am ${dateText} ${hoursText} h`;
|
||||
? `Korrektur am ${dateText} ${hoursText} – ${reason}`
|
||||
: `Korrektur am ${dateText} ${hoursText}`;
|
||||
correctionsListEl.appendChild(li);
|
||||
});
|
||||
|
||||
@@ -361,10 +354,10 @@
|
||||
row.innerHTML = `
|
||||
<td><strong>${week.year} KW${calendarWeekStr}</strong></td>
|
||||
<td>${dateRange}</td>
|
||||
<td>${week.total_hours.toFixed(2)} h</td>
|
||||
<td>${week.soll_stunden.toFixed(2)} h</td>
|
||||
<td class="${overtimeClass}">${overtimeSign}${week.overtime_hours.toFixed(2)} h</td>
|
||||
<td>${week.overtime_taken.toFixed(2)} h</td>
|
||||
<td>${formatHoursMin(week.total_hours)}</td>
|
||||
<td>${formatHoursMin(week.soll_stunden)}</td>
|
||||
<td class="${overtimeClass}">${overtimeSign}${formatHoursMin(week.overtime_hours)}</td>
|
||||
<td>${formatHoursMin(week.overtime_taken)}</td>
|
||||
<td>${week.vacation_days > 0 ? week.vacation_days.toFixed(1) : '-'}</td>
|
||||
`;
|
||||
tableBodyEl.appendChild(row);
|
||||
|
||||
@@ -318,6 +318,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/format-hours.js"></script>
|
||||
<script>
|
||||
async function loadStatsForDiv(statsDiv) {
|
||||
const userId = statsDiv.dataset.userId;
|
||||
@@ -341,13 +342,13 @@
|
||||
const weekOvertimeColor = data.weekOvertimeHours < 0 ? '#dc3545' : (data.weekOvertimeHours > 0 ? '#28a745' : '#666');
|
||||
const sign = data.weekOvertimeHours >= 0 ? '+' : '';
|
||||
statsHTML += `<div class="stats-inline" style="display: inline-block; margin-right: 20px;">
|
||||
<strong>Überstunden:</strong> <span style="color: ${weekOvertimeColor};">${sign}${data.weekOvertimeHours.toFixed(2)} h</span>
|
||||
<strong>Überstunden:</strong> <span style="color: ${weekOvertimeColor};">${sign}${formatHoursMin(data.weekOvertimeHours)}</span>
|
||||
</div>`;
|
||||
}
|
||||
if (data.overtimeOffsetHours !== undefined && data.overtimeOffsetHours !== 0) {
|
||||
statsHTML += `<div class="stats-inline" style="display: inline-block; margin-right: 20px;">
|
||||
<strong>Offset:</strong> <span>${Number(data.overtimeOffsetHours).toFixed(2)} h</span>
|
||||
${data.remainingOvertimeWithOffset !== undefined ? `<span style="color: #28a745;">(verbleibend inkl. Offset: ${Number(data.remainingOvertimeWithOffset).toFixed(2)} h)</span>` : ''}
|
||||
<strong>Offset:</strong> <span>${formatHoursMin(Number(data.overtimeOffsetHours))}</span>
|
||||
${data.remainingOvertimeWithOffset !== undefined ? `<span style="color: #28a745;">(verbleibend inkl. Offset: ${formatHoursMin(Number(data.remainingOvertimeWithOffset))})</span>` : ''}
|
||||
</div>`;
|
||||
}
|
||||
if (data.totalVacationDays !== undefined || data.vacationDays !== undefined) {
|
||||
@@ -513,15 +514,7 @@
|
||||
return new Date(s.replace(' ', 'T') + 'Z');
|
||||
}
|
||||
|
||||
function formatHours(value) {
|
||||
const n = Number(value);
|
||||
if (!Number.isFinite(n)) return '';
|
||||
const sign = n > 0 ? '+' : '';
|
||||
let s = sign + n.toFixed(2);
|
||||
s = s.replace(/\.00$/, '');
|
||||
s = s.replace(/(\.\d)0$/, '$1');
|
||||
return s;
|
||||
}
|
||||
// formatHoursMin aus format-hours.js (window.formatHoursMin)
|
||||
|
||||
function showOvertimeCorrectionReasonModal(opts) {
|
||||
const title = opts && opts.title ? String(opts.title) : 'Grund für die Korrektur';
|
||||
@@ -652,12 +645,12 @@
|
||||
corrections.forEach(c => {
|
||||
const dt = parseSqliteDatetime(c.corrected_at);
|
||||
const dateText = dt ? dt.toLocaleDateString('de-DE') : '';
|
||||
const hoursText = formatHours(c.correction_hours);
|
||||
const hoursText = formatHoursMin(c.correction_hours);
|
||||
const reason = (c && c.reason != null) ? String(c.reason).trim() : '';
|
||||
const li = document.createElement('li');
|
||||
li.textContent = reason
|
||||
? `Korrektur am ${dateText} ${hoursText} h – ${reason}`
|
||||
: `Korrektur am ${dateText} ${hoursText} h`;
|
||||
? `Korrektur am ${dateText} ${hoursText} – ${reason}`
|
||||
: `Korrektur am ${dateText} ${hoursText}`;
|
||||
if (listEl) listEl.appendChild(li);
|
||||
});
|
||||
} catch (e) {
|
||||
@@ -720,7 +713,7 @@
|
||||
// Modal: Grund ist Pflicht
|
||||
showOvertimeCorrectionReasonModal({
|
||||
title: 'Grund für die Überstunden-Korrektur',
|
||||
prompt: `Korrektur: ${value > 0 ? '+' : ''}${value} h`,
|
||||
prompt: `Korrektur: ${value >= 0 ? '+' : ''}${formatHoursMin(value)}`,
|
||||
onCancel: () => {
|
||||
delete this.dataset.modalOpen;
|
||||
this.disabled = false;
|
||||
|
||||
Reference in New Issue
Block a user