|
|
|
|
@ -4,10 +4,49 @@ const mins = document.getElementById('minuten');
|
|
|
|
|
const NewEntryButton = document.getElementById('newEntrySubmitButton')
|
|
|
|
|
const SETStudySaveButton = document.getElementById('SETStudySaveButton')
|
|
|
|
|
const SETMonthGoalSaveButton = document.getElementById('SETMonthGoalSaveButton')
|
|
|
|
|
const SETLdcNameSaveButton = document.getElementById('SETLdcNameSaveButton')
|
|
|
|
|
const rule55hCheck = document.getElementById('rule55hCheck')
|
|
|
|
|
const openViewOfEntry = document.getElementById('openViewOfEntry')
|
|
|
|
|
const openViewOfEntryIcon = document.getElementById('openViewOfEntryIcon')
|
|
|
|
|
const ActivitysTable = document.getElementById('ActivitysTable')
|
|
|
|
|
const timerCard = document.getElementById('timerCard')
|
|
|
|
|
const toggleSortOptions = document.getElementById('toggleSortOptions')
|
|
|
|
|
const sortOptionsRow = document.getElementById('sortOptionsRow')
|
|
|
|
|
const sortFieldButton = document.getElementById('sortFieldButton')
|
|
|
|
|
const sortFieldLabel = document.getElementById('sortFieldLabel')
|
|
|
|
|
const sortFieldMenu = document.getElementById('sortFieldMenu')
|
|
|
|
|
const sortFieldOptions = document.querySelectorAll('.sortFieldOption')
|
|
|
|
|
const sortDirectionToggle = document.getElementById('sortDirectionToggle')
|
|
|
|
|
const sortDirectionIcon = document.getElementById('sortDirectionIcon')
|
|
|
|
|
const shareIcon = document.getElementById('share_icon')
|
|
|
|
|
const shareReportModalEl = document.getElementById('shareReportModal')
|
|
|
|
|
const shareReportStatus = document.getElementById('shareReportStatus')
|
|
|
|
|
const shareReportPreview = document.getElementById('shareReportPreview')
|
|
|
|
|
var allowToSend = false;
|
|
|
|
|
const monate = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];
|
|
|
|
|
const currentDate = new Date();
|
|
|
|
|
|
|
|
|
|
// 55h-Regel (Jahresansicht): wird beim Start aus den Settings geladen und beim Umschalten
|
|
|
|
|
// live aktualisiert, damit getActualDataAndFillView() sie synchron verwenden kann.
|
|
|
|
|
var rule55Active = false;
|
|
|
|
|
|
|
|
|
|
// Individuell vergebbarer Name für "LDC" (SettingsID 4), überall im UI verwendet statt fest "LDC".
|
|
|
|
|
var ldcLabel = 'LDC';
|
|
|
|
|
|
|
|
|
|
// Sortierung der Aktivitäten-Tabelle: wird aus dem Cache (localStorage) geladen/gespeichert.
|
|
|
|
|
var sortField = 'date';
|
|
|
|
|
var sortDirection = 'asc';
|
|
|
|
|
|
|
|
|
|
// Ob die Filter/Sortier-Optionen gerade sichtbar sind (wird ebenfalls im Cache gespeichert).
|
|
|
|
|
// Standardmäßig ausgeblendet, bis der Nutzer sie einmal selbst einblendet.
|
|
|
|
|
var isFilterVisible = false;
|
|
|
|
|
|
|
|
|
|
// Ob die Aktivitäten-Tabelle gerade maximiert ist (Timer-Karte ist dann ausgeblendet).
|
|
|
|
|
var isTableMaximized = false;
|
|
|
|
|
|
|
|
|
|
// Einträge des gerade angezeigten Monats, für den WhatsApp-Bericht (share_icon) wiederverwendet.
|
|
|
|
|
var currentMonthEntries = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Trigger
|
|
|
|
|
@ -15,19 +54,189 @@ const currentDate = new Date();
|
|
|
|
|
|
|
|
|
|
// Wenn das Dokument komplett geladen ist
|
|
|
|
|
document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
|
|
initDB().then(() => {
|
|
|
|
|
initDB().then(async () => {
|
|
|
|
|
console.log('IndexedDB erfolgreich initialisiert.');
|
|
|
|
|
// Hier kannst du die App weiter initialisieren, z.B. Daten laden oder die UI aufbauen
|
|
|
|
|
|
|
|
|
|
// 55h-Regel Einstellung laden, bevor die erste Jahresansicht berechnet wird
|
|
|
|
|
await loadRule55Setting();
|
|
|
|
|
|
|
|
|
|
// LDC-Bezeichnung laden, bevor die Tabelle erstmalig gefüllt wird
|
|
|
|
|
await loadLdcLabel();
|
|
|
|
|
|
|
|
|
|
// Gespeicherte Sortierung der Aktivitäten-Tabelle aus dem Cache laden
|
|
|
|
|
loadSortPreference();
|
|
|
|
|
|
|
|
|
|
// Gespeicherte Sichtbarkeit der Filter/Sortier-Optionen aus dem Cache laden
|
|
|
|
|
loadFilterVisibility();
|
|
|
|
|
|
|
|
|
|
// Bildschirm mit dem Inhalt für den aktuellen Tag füllen
|
|
|
|
|
getActualDataAndFillView();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//loadInitialData();
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
console.error('Fehler bei der Initialisierung der IndexedDB:', error);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Behebt die Bootstrap-Konsolenwarnung "Blocked aria-hidden on an element because its
|
|
|
|
|
// descendant retained focus": beim Schließen eines Modals (z.B. per "X"-Button) setzt
|
|
|
|
|
// Bootstrap aria-hidden="true", obwohl der geklickte Button noch fokussiert ist. Fix: Fokus
|
|
|
|
|
// vor dem Ausblenden gezielt vom Modal wegnehmen. Gilt für alle Modals der Seite.
|
|
|
|
|
document.querySelectorAll('.modal').forEach(modalEl => {
|
|
|
|
|
modalEl.addEventListener('hide.bs.modal', () => {
|
|
|
|
|
if (document.activeElement && modalEl.contains(document.activeElement)) {
|
|
|
|
|
document.activeElement.blur()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Lädt die 55h-Regel Einstellung (SettingsID 3) aus der DB, setzt rule55Active
|
|
|
|
|
// und synchronisiert die Checkbox sowie den Badge in der Jahres-Card.
|
|
|
|
|
async function loadRule55Setting() {
|
|
|
|
|
const result = await getAllEntries('settings')
|
|
|
|
|
const setting = result.find(element => element.SettingsID === 3)
|
|
|
|
|
rule55Active = (setting == undefined) ? false : !!parseInt(setting.SettingsValue)
|
|
|
|
|
rule55hCheck.checked = rule55Active
|
|
|
|
|
updateRule55Badge()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Zeigt/versteckt den "55h-Regel aktiv"-Hinweis an der Jahres-Card
|
|
|
|
|
function updateRule55Badge() {
|
|
|
|
|
document.getElementById('rule55Badge').classList.toggle('d-none', !rule55Active)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Einstellungen wenn die 55h-Regel umgeschaltet wird
|
|
|
|
|
rule55hCheck.addEventListener('change', () => {
|
|
|
|
|
rule55Active = rule55hCheck.checked
|
|
|
|
|
updateRule55Badge()
|
|
|
|
|
|
|
|
|
|
const Rule55SettingsData = {
|
|
|
|
|
SettingsID: 3,
|
|
|
|
|
SettingsValue: rule55Active ? 1 : 0,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getAllEntries('settings')
|
|
|
|
|
.then(function(result) {
|
|
|
|
|
const SETDBData = result.find(element => element.SettingsID === 3)
|
|
|
|
|
|
|
|
|
|
if (SETDBData != undefined) {
|
|
|
|
|
updateEntry(SETDBData.id, 'settings', Rule55SettingsData)
|
|
|
|
|
} else {
|
|
|
|
|
addEntry(Rule55SettingsData, 'settings')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Jahresansicht mit/ohne Deckel neu berechnen
|
|
|
|
|
getActualDataAndFillView(cursorMonth, cursorYear)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// TABELLE MAXIMIEREN
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// Aktivitäten-Tabelle vergrößern/verkleinern: Timer-Karte klappt beim Maximieren
|
|
|
|
|
// animiert weg, um Platz zu schaffen; die Tabelle wächst gleichzeitig.
|
|
|
|
|
openViewOfEntry.addEventListener('click', () => {
|
|
|
|
|
isTableMaximized = !isTableMaximized
|
|
|
|
|
ActivitysTable.classList.toggle('ActivitysTableMaximized', isTableMaximized)
|
|
|
|
|
timerCard.classList.toggle('timerCollapsed', isTableMaximized)
|
|
|
|
|
openViewOfEntryIcon.src = isTableMaximized
|
|
|
|
|
? openViewOfEntryIcon.src.replace('open.png', 'close.png')
|
|
|
|
|
: openViewOfEntryIcon.src.replace('close.png', 'open.png')
|
|
|
|
|
openViewOfEntry.title = isTableMaximized ? 'Tabelle minimieren' : 'Tabelle maximieren'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// SORTIERUNG DER AKTIVITÄTEN-TABELLE
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// Lädt die gespeicherte Sortierung aus dem Cache (localStorage) und synchronisiert die Steuerelemente
|
|
|
|
|
function loadSortPreference() {
|
|
|
|
|
try {
|
|
|
|
|
const saved = JSON.parse(localStorage.getItem('piomintTableSort'))
|
|
|
|
|
if (saved && saved.field) {
|
|
|
|
|
sortField = saved.field
|
|
|
|
|
sortDirection = (saved.direction === 'desc') ? 'desc' : 'asc'
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Sortierung konnte nicht aus dem Cache geladen werden:', error)
|
|
|
|
|
}
|
|
|
|
|
const selectedOption = Array.from(sortFieldOptions).find(option => option.dataset.value === sortField)
|
|
|
|
|
sortFieldLabel.innerText = selectedOption ? selectedOption.dataset.label : 'Datum'
|
|
|
|
|
sortDirectionIcon.innerText = (sortDirection === 'asc') ? 'A → Z' : 'Z → A'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Speichert die aktuelle Sortierung im Cache (localStorage)
|
|
|
|
|
function saveSortPreference() {
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem('piomintTableSort', JSON.stringify({ field: sortField, direction: sortDirection }))
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Sortierung konnte nicht im Cache gespeichert werden:', error)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Eigener Dropdown für die Sortier-Eigenschaft (statt <select>) öffnen/schließen
|
|
|
|
|
sortFieldButton.addEventListener('click', (event) => {
|
|
|
|
|
event.stopPropagation()
|
|
|
|
|
sortFieldMenu.classList.toggle('d-none')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Außerhalb des Menüs klicken schließt es wieder
|
|
|
|
|
document.addEventListener('click', (event) => {
|
|
|
|
|
if (!sortFieldMenu.classList.contains('d-none') && !sortFieldMenu.contains(event.target) && event.target !== sortFieldButton) {
|
|
|
|
|
sortFieldMenu.classList.add('d-none')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
sortFieldOptions.forEach(option => {
|
|
|
|
|
option.addEventListener('click', () => {
|
|
|
|
|
sortField = option.dataset.value
|
|
|
|
|
sortFieldLabel.innerText = option.dataset.label
|
|
|
|
|
sortFieldMenu.classList.add('d-none')
|
|
|
|
|
saveSortPreference()
|
|
|
|
|
getActualDataAndFillView(cursorMonth, cursorYear)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
sortDirectionToggle.addEventListener('click', () => {
|
|
|
|
|
sortDirection = (sortDirection === 'asc') ? 'desc' : 'asc'
|
|
|
|
|
sortDirectionIcon.innerText = (sortDirection === 'asc') ? 'A → Z' : 'Z → A'
|
|
|
|
|
saveSortPreference()
|
|
|
|
|
getActualDataAndFillView(cursorMonth, cursorYear)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// FILTER/SORTIER-OPTIONEN EIN-/AUSBLENDEN
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// Lädt die gespeicherte Sichtbarkeit der Filter-Optionen aus dem Cache (localStorage)
|
|
|
|
|
function loadFilterVisibility() {
|
|
|
|
|
try {
|
|
|
|
|
const saved = localStorage.getItem('piomintFilterVisible')
|
|
|
|
|
if (saved !== null) {
|
|
|
|
|
isFilterVisible = (saved === 'true')
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Filter-Sichtbarkeit konnte nicht aus dem Cache geladen werden:', error)
|
|
|
|
|
}
|
|
|
|
|
sortOptionsRow.classList.toggle('sortOptionsCollapsed', !isFilterVisible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toggleSortOptions.addEventListener('click', () => {
|
|
|
|
|
isFilterVisible = !isFilterVisible
|
|
|
|
|
sortOptionsRow.classList.toggle('sortOptionsCollapsed', !isFilterVisible)
|
|
|
|
|
// Offenes Dropdown-Menü beim Einklappen der Filterzeile mit schließen
|
|
|
|
|
if (!isFilterVisible) {
|
|
|
|
|
sortFieldMenu.classList.add('d-none')
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem('piomintFilterVisible', isFilterVisible)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Filter-Sichtbarkeit konnte nicht im Cache gespeichert werden:', error)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Änderungen überwachen damit die das Formular nicht zu früh abgesendet wird
|
|
|
|
|
@ -160,6 +369,127 @@ SETMonthGoalSaveButton.addEventListener('click', () => {
|
|
|
|
|
SETMonthGoalSaveButton.classList.add('d-none')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Lädt die individuelle LDC-Bezeichnung (SettingsID 4) aus der DB, setzt ldcLabel,
|
|
|
|
|
// füllt das Einstellungen-Feld vor und wendet den Namen überall im UI an.
|
|
|
|
|
async function loadLdcLabel() {
|
|
|
|
|
const result = await getAllEntries('settings')
|
|
|
|
|
const setting = result.find(element => element.SettingsID === 4)
|
|
|
|
|
ldcLabel = (setting == undefined || !setting.SettingsValue) ? 'LDC' : setting.SettingsValue
|
|
|
|
|
document.getElementById('ldcNameInput').value = ldcLabel
|
|
|
|
|
applyLdcLabel()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setzt die aktuelle LDC-Bezeichnung überall dort, wo sie im UI (außerhalb der Tabelle) auftaucht.
|
|
|
|
|
// Die Tabelle selbst bekommt den Namen bei jedem Render über fillTableWithEntries(...).
|
|
|
|
|
function applyLdcLabel() {
|
|
|
|
|
document.getElementById('ldcCheckLabel').innerText = ldcLabel
|
|
|
|
|
document.getElementById('editldcCheckLabel').innerText = ldcLabel
|
|
|
|
|
document.getElementById('monthHourLDCLabel').innerText = ldcLabel
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SETLdcNameSaveButton.addEventListener('click', () => {
|
|
|
|
|
getAllEntries('settings')
|
|
|
|
|
.then(function(result) {
|
|
|
|
|
const SETDBData = result.find(element => element.SettingsID === 4)
|
|
|
|
|
actualSettingsEntryID = SETDBData ? SETDBData.id : undefined;
|
|
|
|
|
actualSettings = SETDBData ? SETDBData.SettingsValue : undefined;
|
|
|
|
|
|
|
|
|
|
// AKTUELLE DATEN AUS FELD ÜBERNHEMEN - bei leerem Feld auf "LDC" zurückfallen
|
|
|
|
|
var ActInput = document.getElementById('ldcNameInput').value.trim() || 'LDC'
|
|
|
|
|
document.getElementById('ldcNameInput').value = ActInput
|
|
|
|
|
|
|
|
|
|
const LdcNameSettingsData = {
|
|
|
|
|
SettingsID: 4,
|
|
|
|
|
SettingsValue: ActInput,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ÜBERPRÜFEN OB EIN EINTRAG MTI DER SETTINGS ID VORHANDEN IST - WENN JA DANN UPDATE WENN NEIN DANN NEUEN ERSTELLEN
|
|
|
|
|
if ( actualSettings != undefined ) {
|
|
|
|
|
updateEntry(actualSettingsEntryID, 'settings', LdcNameSettingsData)
|
|
|
|
|
} else {
|
|
|
|
|
addEntry(LdcNameSettingsData, 'settings')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ldcLabel = ActInput
|
|
|
|
|
applyLdcLabel()
|
|
|
|
|
// Tabelle neu füllen, damit die Typ-Spalte den neuen Namen sofort übernimmt
|
|
|
|
|
getActualDataAndFillView(cursorMonth, cursorYear)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
SETLdcNameSaveButton.classList.add('d-none')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// BERICHT FÜR WHATSAPP TEILEN
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// Baut den vorformatierten Bericht für den gerade angezeigten Monat (WhatsApp-Formatierung: *fett*)
|
|
|
|
|
function buildMonthReportText() {
|
|
|
|
|
const monthLabel = `${monate[cursorMonth]} ${cursorYear}`
|
|
|
|
|
const dienstHours = document.getElementById('monthHourService').innerText
|
|
|
|
|
const bibelstudien = document.getElementById('studysinput').value
|
|
|
|
|
const ldcHours = document.getElementById('monthHourLDC').innerText
|
|
|
|
|
|
|
|
|
|
// Sonstige Einträge nach ihrem individuellen Bemerkungstext gruppieren und Stunden je Gruppe summieren
|
|
|
|
|
const sonstigeGroups = {}
|
|
|
|
|
currentMonthEntries
|
|
|
|
|
.filter(entry => entry.type === 3)
|
|
|
|
|
.forEach(entry => {
|
|
|
|
|
const label = entry.sondertext || 'Sonstiges'
|
|
|
|
|
sonstigeGroups[label] = (sonstigeGroups[label] || 0) + entry.duration
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
var message = `Bericht: *${monthLabel}*\n`
|
|
|
|
|
message += `Dienst: ${dienstHours}h\n`
|
|
|
|
|
message += `Bibelstudien: ${bibelstudien}\n`
|
|
|
|
|
message += `Bemerkungen:\n`
|
|
|
|
|
message += `• ${ldcLabel}: ${ldcHours}h`
|
|
|
|
|
|
|
|
|
|
Object.keys(sonstigeGroups).forEach(label => {
|
|
|
|
|
message += `\n• ${label}: ${formatDuration(sonstigeGroups[label], true)}h`
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return message
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Kopiert Text in die Zwischenablage - mit Fallback für Umgebungen ohne Clipboard-API
|
|
|
|
|
async function copyTextToClipboard(text) {
|
|
|
|
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
|
|
|
await navigator.clipboard.writeText(text)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const textarea = document.createElement('textarea')
|
|
|
|
|
textarea.value = text
|
|
|
|
|
textarea.style.position = 'fixed'
|
|
|
|
|
textarea.style.opacity = '0'
|
|
|
|
|
document.body.appendChild(textarea)
|
|
|
|
|
textarea.select()
|
|
|
|
|
document.execCommand('copy')
|
|
|
|
|
document.body.removeChild(textarea)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Bestätigung als Vorschau-Modal statt kurzem Icon-Blitz: so sieht man den Bericht direkt
|
|
|
|
|
// (auch praktisch, wenn man ihn gar nicht kopieren, sondern nur ansehen möchte) und kann
|
|
|
|
|
// in Ruhe wieder schließen.
|
|
|
|
|
shareIcon.addEventListener('click', () => {
|
|
|
|
|
const message = buildMonthReportText()
|
|
|
|
|
shareReportPreview.innerText = message
|
|
|
|
|
|
|
|
|
|
copyTextToClipboard(message)
|
|
|
|
|
.then(() => {
|
|
|
|
|
shareReportStatus.innerText = '✓ In die Zwischenablage kopiert'
|
|
|
|
|
shareReportStatus.style.color = 'rgb(120,170,86)'
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error('Bericht konnte nicht in die Zwischenablage kopiert werden:', error)
|
|
|
|
|
shareReportStatus.innerText = 'Kopieren nicht möglich - Text unten manuell markieren'
|
|
|
|
|
shareReportStatus.style.color = '#dc3545'
|
|
|
|
|
})
|
|
|
|
|
.finally(() => {
|
|
|
|
|
new bootstrap.Modal(shareReportModalEl).show()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function getActualDataAndFillView(monat = currentDate.getMonth(), jahr = currentDate.getFullYear()) {
|
|
|
|
|
try {
|
|
|
|
|
@ -184,12 +514,13 @@ async function getActualDataAndFillView(monat = currentDate.getMonth(), jahr = c
|
|
|
|
|
|
|
|
|
|
// Filter funktion aufrufen und entsprechend mit dem aktuellen Datum füllen
|
|
|
|
|
const filteredEntries = await filterEntriesByMonthYear(monat === 12 ? 1 : monat + 1, jahr);
|
|
|
|
|
currentMonthEntries = filteredEntries
|
|
|
|
|
|
|
|
|
|
console.log("update-complete")
|
|
|
|
|
console.log(jahr)
|
|
|
|
|
|
|
|
|
|
// Tabelle mit den aktuellen informationen füllen (funktion triggern und Daten übergeben)
|
|
|
|
|
fillTableWithEntries(filteredEntries)
|
|
|
|
|
fillTableWithEntries(filteredEntries, sortField, sortDirection, ldcLabel)
|
|
|
|
|
|
|
|
|
|
// Ausgabe der Daten in den Log für DEV möglich
|
|
|
|
|
// console.log('Gefilterte Einträge für September 2024:', filteredEntries);
|
|
|
|
|
@ -216,12 +547,15 @@ async function getActualDataAndFillView(monat = currentDate.getMonth(), jahr = c
|
|
|
|
|
document.getElementById('monthHourOther').innerText = formatDuration(sumDurations(filteredEntries,3,true), true)
|
|
|
|
|
|
|
|
|
|
// Jahres Ansicht füllen (Dienstjahr, gekoppelt an den gerade angezeigten Monat/Jahr)
|
|
|
|
|
// Bei aktiver 55h-Regel wird jeder Monat mit LDC/Sonstiges-Anteil auf max. 55h gedeckelt,
|
|
|
|
|
// reine Dienststunden zählen dabei immer voll (siehe calculateServiceYearTotal).
|
|
|
|
|
var requestServiceYear = getServiceYear(new Date(jahr, monat, 1));
|
|
|
|
|
var yearData = await filterEntriesByServiceYear(requestServiceYear)
|
|
|
|
|
yearData = formatDuration(sumDurations(yearData, null, true), true)
|
|
|
|
|
var yearEntries = await filterEntriesByServiceYear(requestServiceYear)
|
|
|
|
|
var yearData = formatDuration(calculateServiceYearTotal(yearEntries, rule55Active), true)
|
|
|
|
|
document.getElementById('yearHours').innerText = yearData
|
|
|
|
|
document.getElementById('yearRest').innerText = 600 - parseInt(yearData)
|
|
|
|
|
document.getElementById('prBarYear').style.width = `${Math.round((100/600)*parseInt(yearData))}%`
|
|
|
|
|
updateRule55Badge()
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Fehler bei der Initialisierung oder Filterung:', error);
|
|
|
|
|
@ -367,9 +701,10 @@ document.getElementById('dashbord_month_area').addEventListener('click', () =>{
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.replace('closeMonthArea', 'openMonthArea')
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.add(['openMonthArea'])
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.add(['ActiveMonth'])
|
|
|
|
|
document.getElementById('ActivitysTable').classList.add(['shrinkActivitys'])
|
|
|
|
|
document.getElementById('ActivitysTable').classList.replace('growActivitys', 'shrinkActivitys')
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.remove('mt-4')
|
|
|
|
|
// ActivitysTable ist jetzt flex:1 1 auto (siehe custom.css) und macht der wachsenden
|
|
|
|
|
// Monatskarte automatisch Platz - kein manuelles shrinkActivitys/growActivitys mehr nötig,
|
|
|
|
|
// das würde der Flex-Berechnung sonst mit einer festen vh-Höhe in die Quere kommen.
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.remove('mt-3')
|
|
|
|
|
// document.getElementById('dashbord_year_area').classList.add('fade-out')
|
|
|
|
|
// Für jedes ausgewählte Element die neue Klasse hinzufügen
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
@ -385,7 +720,7 @@ document.getElementById('dashbord_month_area').addEventListener('click', () =>{
|
|
|
|
|
} else {
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.remove('ActiveMonth')
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.replace('openMonthArea', 'closeMonthArea')
|
|
|
|
|
document.getElementById('ActivitysTable').classList.replace('shrinkActivitys', 'growActivitys')
|
|
|
|
|
document.getElementById('dashbord_month_area').classList.add('mt-3')
|
|
|
|
|
monthEntrys.forEach(element => {
|
|
|
|
|
element.classList.replace('fade-in', 'fade-out');
|
|
|
|
|
});
|
|
|
|
|
|