Please help me!
Hello, I have a problem with my js-code. Thats the error: Uncaught SyntaxError: expected expression, got ')'main.js:1032:2 And thats the code: // static/js/main.js // Stand: Korrigiert, aufgeräumt, korrektes Feedback im Schichtplan document.addEventListener('DOMContentLoaded', function() { console.log("########## DOMContentLoaded START ##########"); // === Globales Objekt für Daten aus Templates === // Wird einmalig beim Laden der Seite gefüllt window.schichtplanerData = {}; try { const empDataElem = document.getElementById('employeeDataJson'); const shiftDictElem = document.getElementById('shiftTypesDataJson'); // Dict mit Objekten const allShiftsElem = document.getElementById('allShiftTypesJson'); // Dict {id: obj} für Modal const allGroupsElem = document.getElementById('allMachineGroupsJson'); // Dict {id: obj} für Modal const qualiLevelsElem = document.getElementById('qualificationLevelsJson'); // Parse JSON data, provide empty objects as fallbacks window.schichtplanerData.employeeDict = empDataElem ? JSON.parse(empDataElem.textContent || '{}') : {}; window.schichtplanerData.shiftTypesDict = shiftDictElem ? JSON.parse(shiftDictElem.textContent || '{}') : {}; window.schichtplanerData.allShiftTypes = allShiftsElem ? JSON.parse(allShiftsElem.textContent || '{}') : {}; window.schichtplanerData.machineGroupsDict = allGroupsElem ? JSON.parse(allGroupsElem.textContent || '{}') : {}; window.schichtplanerData.qualificationLevelsData = qualiLevelsElem ? JSON.parse(qualiLevelsElem.textContent || '{}') : {}; console.log("Globale Daten geladen:", window.schichtplanerData); } catch (e) { console.error("Fehler beim Parsen der globalen JSON-Daten!", e); // Setze leere Fallbacks window.schichtplanerData = { employeeDict:{}, shiftTypesDict:{}, allShiftTypes:{}, machineGroupsDict:{}, qualificationLevelsData:{} }; } // === ENDE Globale Daten === // PASTE START 1: Ersetzt den ursprünglichen Modal-Steuerungsblock // === Modul: Modal Steuerung (ANGEPASST für generisches Öffnen) === const commonModalElement = document.getElementById("commonModal"); const commonModalTitle = commonModalElement ? commonModalElement.querySelector("#modalTitle") : null; const commonModalBody = commonModalElement ? commonModalElement.querySelector("#modalBody") : null; // const commonCloseModalBtn = commonModalElement ? commonModalElement.querySelector(".close-modal-btn") : null; // Nicht mehr global gebraucht // Das spezielle Einstellungs-Modal für Schichtarten holen const settingsModalElement = document.getElementById("shiftTypeSettingsModal"); const settingsModalTitle = settingsModalElement ? settingsModalElement.querySelector("#shiftTypeSettingsModalTitle") : null; const settingsModalBody = settingsModalElement ? settingsModalElement.querySelector("#shiftTypeSettingsModalBody") : null; // const settingsCloseModalBtn = settingsModalElement ? settingsModalElement.querySelector(".close-modal-btn") : null; // Nicht mehr global gebraucht // GENERISCHE Funktion zum Öffnen eines Modals // targetModalId: ID des Modals, das geöffnet werden soll ('commonModal' oder 'shiftTypeSettingsModal') // title: Titel für das Modal // contentSourceId: ID des Containers im HTML, dessen Inhalt kopiert werden soll // contentType: 'form' (nur erstes Formular kopieren) oder 'full' (gesamten Inhalt kopieren) function openModalGeneric(targetModalId, title, contentSourceId, contentType = 'form') { const modalToOpen = document.getElementById(targetModalId); // IDs für Titel/Body aus dem spezifischen Modal holen const modalTitleElement = modalToOpen ? modalToOpen.querySelector('h2') : null; // Nimmt die erste H2 im Modal const modalBodyElement = modalToOpen ? modalToOpen.querySelector('.modal-content > div:last-of-type') : null; // Nimmt das letzte Div im .modal-content const contentSourceContainer = document.getElementById(contentSourceId); if (modalToOpen && modalTitleElement && modalBodyElement && contentSourceContainer) { modalTitleElement.textContent = title || 'Dialog'; // Titel setzen let contentToInsert = null; if (contentType === 'full') { // Kopiere den gesamten *Inhalt* des Quellcontainers contentToInsert = contentSourceContainer.innerHTML; console.log(`Modal Content Type 'full' for ${contentSourceId}`); } else { // Default: 'form' // Kopiere nur das *erste Formular* aus dem Quellcontainer const formTemplate = contentSourceContainer.querySelector('form'); if (formTemplate) { contentToInsert = formTemplate.cloneNode(true); // Klonen, damit Original bleibt console.log(`Modal Content Type 'form' for ${contentSourceId}`); } else { console.error(`Kein Element im Container #${contentSourceId} gefunden für contentType 'form'.`); modalBodyElement.innerHTML = 'Fehler: Formular konnte nich

Hello, I have a problem with my js-code.
Thats the error: Uncaught SyntaxError: expected expression, got ')'main.js:1032:2
And thats the code:
// static/js/main.js
// Stand: Korrigiert, aufgeräumt, korrektes Feedback im Schichtplan
document.addEventListener('DOMContentLoaded', function() {
console.log("########## DOMContentLoaded START ##########");
// === Globales Objekt für Daten aus Templates ===
// Wird einmalig beim Laden der Seite gefüllt
window.schichtplanerData = {};
try {
const empDataElem = document.getElementById('employeeDataJson');
const shiftDictElem = document.getElementById('shiftTypesDataJson'); // Dict mit Objekten
const allShiftsElem = document.getElementById('allShiftTypesJson'); // Dict {id: obj} für Modal
const allGroupsElem = document.getElementById('allMachineGroupsJson'); // Dict {id: obj} für Modal
const qualiLevelsElem = document.getElementById('qualificationLevelsJson');
// Parse JSON data, provide empty objects as fallbacks
window.schichtplanerData.employeeDict = empDataElem ? JSON.parse(empDataElem.textContent || '{}') : {};
window.schichtplanerData.shiftTypesDict = shiftDictElem ? JSON.parse(shiftDictElem.textContent || '{}') : {};
window.schichtplanerData.allShiftTypes = allShiftsElem ? JSON.parse(allShiftsElem.textContent || '{}') : {};
window.schichtplanerData.machineGroupsDict = allGroupsElem ? JSON.parse(allGroupsElem.textContent || '{}') : {};
window.schichtplanerData.qualificationLevelsData = qualiLevelsElem ? JSON.parse(qualiLevelsElem.textContent || '{}') : {};
console.log("Globale Daten geladen:", window.schichtplanerData);
} catch (e) {
console.error("Fehler beim Parsen der globalen JSON-Daten!", e);
// Setze leere Fallbacks
window.schichtplanerData = { employeeDict:{}, shiftTypesDict:{}, allShiftTypes:{}, machineGroupsDict:{}, qualificationLevelsData:{} };
}
// === ENDE Globale Daten ===
// PASTE START 1: Ersetzt den ursprünglichen Modal-Steuerungsblock
// === Modul: Modal Steuerung (ANGEPASST für generisches Öffnen) ===
const commonModalElement = document.getElementById("commonModal");
const commonModalTitle = commonModalElement ? commonModalElement.querySelector("#modalTitle") : null;
const commonModalBody = commonModalElement ? commonModalElement.querySelector("#modalBody") : null;
// const commonCloseModalBtn = commonModalElement ? commonModalElement.querySelector(".close-modal-btn") : null; // Nicht mehr global gebraucht
// Das spezielle Einstellungs-Modal für Schichtarten holen
const settingsModalElement = document.getElementById("shiftTypeSettingsModal");
const settingsModalTitle = settingsModalElement ? settingsModalElement.querySelector("#shiftTypeSettingsModalTitle") : null;
const settingsModalBody = settingsModalElement ? settingsModalElement.querySelector("#shiftTypeSettingsModalBody") : null;
// const settingsCloseModalBtn = settingsModalElement ? settingsModalElement.querySelector(".close-modal-btn") : null; // Nicht mehr global gebraucht
// GENERISCHE Funktion zum Öffnen eines Modals
// targetModalId: ID des Modals, das geöffnet werden soll ('commonModal' oder 'shiftTypeSettingsModal')
// title: Titel für das Modal
// contentSourceId: ID des Containers im HTML, dessen Inhalt kopiert werden soll
// contentType: 'form' (nur erstes Formular kopieren) oder 'full' (gesamten Inhalt kopieren)
function openModalGeneric(targetModalId, title, contentSourceId, contentType = 'form') {
const modalToOpen = document.getElementById(targetModalId);
// IDs für Titel/Body aus dem spezifischen Modal holen
const modalTitleElement = modalToOpen ? modalToOpen.querySelector('h2') : null; // Nimmt die erste H2 im Modal
const modalBodyElement = modalToOpen ? modalToOpen.querySelector('.modal-content > div:last-of-type') : null; // Nimmt das letzte Div im .modal-content
const contentSourceContainer = document.getElementById(contentSourceId);
if (modalToOpen && modalTitleElement && modalBodyElement && contentSourceContainer) {
modalTitleElement.textContent = title || 'Dialog'; // Titel setzen
let contentToInsert = null;
if (contentType === 'full') {
// Kopiere den gesamten *Inhalt* des Quellcontainers
contentToInsert = contentSourceContainer.innerHTML;
console.log(`Modal Content Type 'full' for ${contentSourceId}`);
} else { // Default: 'form'
// Kopiere nur das *erste Formular* aus dem Quellcontainer
const formTemplate = contentSourceContainer.querySelector('form');
if (formTemplate) {
contentToInsert = formTemplate.cloneNode(true); // Klonen, damit Original bleibt
console.log(`Modal Content Type 'form' for ${contentSourceId}`);
} else {
console.error(`Kein
// --- Modul 8: Maschinen & Gruppen Bearbeiten/Löschen ---
const mgmtContainer = document.getElementById('groups-and-machines-list');
const editGroupFormTemplate = document.getElementById('editGroupFormTemplate');
const editMachineFormTemplate = document.getElementById('editMachineFormTemplate');
// Stelle sicher, dass alle Elemente auf der SEITE vorhanden sind UND das Modal existiert
if (mgmtContainer && editGroupFormTemplate && editMachineFormTemplate && modal) {
console.log("Schichtplaner JS: Initialisiere Maschinen/Gruppen Edit/Delete Logik.");
// === Event Listener für Klicks im Verwaltungsbereich ===
mgmtContainer.addEventListener('click', function(event) {
const targetButton = event.target.closest('button'); // Finde den geklickten Button
if (!targetButton) return; // Ignoriere Klicks, die nicht auf Buttons sind
// --- GRUPPE BEARBEITEN ---
if (targetButton.classList.contains('edit-group-btn')) {
event.preventDefault(); // Verhindere Standardverhalten
const groupId = targetButton.dataset.groupId;
const modalTitle = targetButton.dataset.modalTitle;
console.log(`Gruppe Bearbeiten geklickt für ID: ${groupId}`);
// API-Call zum Holen der Gruppendaten
fetch(`/api/group/${groupId}`)
.then(response => response.ok ? response.json() : response.json().then(err => Promise.reject(err)))
.then(result => {
if (result.status === 'success' && result.group) {
const groupData = result.group;
console.log("Gruppendaten geladen:", groupData);
// Öffne das Modal mit der GRUPPEN-Bearbeiten-Vorlage
openModalGeneric('commonModal', modalTitle || `Gruppe bearbeiten`, 'editGroupFormTemplate', 'form');
// Finde das Formular im JETZT SICHTBAREN Modal Body
const visibleEditForm = modalBody.querySelector('.edit-group-form');
if (visibleEditForm) {
// Fülle die Formularfelder mit den Daten
const nameInput = visibleEditForm.querySelector('input[name="name"]');
const abbrInput = visibleEditForm.querySelector('input[name="abbreviation"]');
const colorInput = visibleEditForm.querySelector('input[name="color"]');
if(nameInput) nameInput.value = groupData.name || '';
if(abbrInput) abbrInput.value = groupData.abbreviation || ''; // Abkürzung füllen
if(colorInput) colorInput.value = groupData.color || '#D0D0D0'; // Farbe füllen
// WICHTIG: Alten Submit-Listener entfernen (durch Klonen) und neuen hinzufügen
const newForm = visibleEditForm.cloneNode(true);
visibleEditForm.parentNode.replaceChild(newForm, visibleEditForm);
newForm.addEventListener('submit', (e) => {
e.preventDefault();
handleEditGroupSubmit(groupId, newForm); // Ruft den Submit Handler auf
});
} else { console.error("Konnte .edit-group-form im Modal nicht finden."); }
} else { throw new Error(result.message || "Fehler beim Laden der Gruppendaten"); }
})
.catch(error => { console.error("Fehler:", error); alert(`Fehler: ${error.message}`); });
}
// --- GRUPPE LÖSCHEN ---
else if (targetButton.classList.contains('delete-group-btn')) {
event.preventDefault();
const groupId = targetButton.dataset.groupId;
const groupName = targetButton.dataset.groupName || 'diese Gruppe';
if (confirm(`Gruppe '${groupName}' wirklich löschen? Zugeordnete Maschinen, Personalbedarf und Quali-Anforderungen gehen verloren!`)) {
console.log(`Löschen bestätigt für Gruppe ID: ${groupId}`);
fetch(`/api/group/${groupId}`, { method: 'DELETE', headers: { 'Accept': 'application/json' } })
.then(response => response.json().then(data => ({ ok: response.ok, data: data })))
.then(result => {
if (result.ok && result.data.status === 'success') {
console.log("Gruppen-Löschen erfolgreich:", result.data.message);
const cardToRemove = document.getElementById(`group-card-${groupId}`);
if (cardToRemove) { cardToRemove.remove(); } // Entferne ganze Karte
// Optional: Flash-Nachricht hinzufügen
} else { throw new Error(result.data.message || 'Fehler beim Löschen der Gruppe'); }
})
.catch(error => { console.error("Fehler beim Gruppen-Löschen:", error); alert(`Fehler: ${error.message}`); });
} else { console.log("Löschen der Gruppe abgebrochen."); }
}
// --- MASCHINE BEARBEITEN ---
else if (targetButton.classList.contains('edit-machine-btn')) {
event.preventDefault();
const machineId = targetButton.dataset.machineId;
const modalTitle = targetButton.dataset.modalTitle;
console.log(`Maschine Bearbeiten geklickt für ID: ${machineId}`);
fetch(`/api/machine/${machineId}`) // API holt Maschine UND Gruppenliste
.then(response => response.ok ? response.json() : response.json().then(err => Promise.reject(err)))
.then(result => {
if (result.status === 'success' && result.machine && result.groups !== undefined) {
const machineData = result.machine;
const groupOptions = result.groups;
// Öffne das Modal mit der MASCHINEN-Bearbeiten-Vorlage
openModalGeneric('commonModal', modalTitle || 'Maschine bearbeiten', 'editMachineFormTemplate', 'form');
// Finde das Formular im JETZT SICHTBAREN Modal Body
const visibleEditForm = modalBody.querySelector('.edit-machine-form');
if (visibleEditForm) {
const nameInput = visibleEditForm.querySelector('input[name="name"]');
const groupSelect = visibleEditForm.querySelector('select[name="group_id"]');
// Dynamische IDs setzen (optional aber besser für Labels)
if(nameInput) nameInput.id = `machine_name_edit_${machineId}`;
if(groupSelect) groupSelect.id = `machine_group_edit_${machineId}`;
const nameLabel = nameInput ? nameInput.previousElementSibling : null;
const groupLabel = groupSelect ? groupSelect.previousElementSibling : null;
if (nameLabel && nameInput) nameLabel.setAttribute('for', nameInput.id);
if (groupLabel && groupSelect) groupLabel.setAttribute('for', groupSelect.id);
// Felder füllen
if (nameInput) nameInput.value = machineData.name || '';
if (groupSelect) {
// Alte Optionen löschen, neue hinzufügen
while (groupSelect.options.length > 1) { groupSelect.remove(1); }
groupOptions.forEach(group => { const option = document.createElement('option'); option.value = group.id; option.textContent = group.name; groupSelect.appendChild(option); });
groupSelect.value = machineData.group_id || '0'; // Wert setzen
}
// Alten Listener entfernen, neuen hinzufügen
const newForm = visibleEditForm.cloneNode(true);
visibleEditForm.parentNode.replaceChild(newForm, visibleEditForm);
newForm.addEventListener('submit', (e) => { e.preventDefault(); handleEditMachineSubmit(machineId, newForm); });
} else { console.error("Konnte .edit-machine-form im Modal nicht finden."); }
} else { throw new Error(result.message || "Fehler Laden Maschinendaten/Gruppen"); }
})
.catch(error => { console.error("Fehler:", error); alert(`Fehler: ${error.message}`); });
}
// --- MASCHINE LÖSCHEN ---
else if (targetButton.classList.contains('delete-machine-btn')) {
event.preventDefault();
const machineId = targetButton.dataset.machineId;
const machineName = targetButton.dataset.machineName || 'diese Maschine';
if (confirm(`Maschine '${machineName}' wirklich löschen?`)) {
console.log(`Löschen bestätigt für Maschine ID: ${machineId}`);
fetch(`/api/machine/${machineId}`, { method: 'DELETE', headers: { 'Accept': 'application/json' } })
.then(response => response.json().then(data => ({ ok: response.ok, data: data })))
.then(result => {
if (result.ok && result.data.status === 'success') {
console.log("Maschinen-Löschen erfolgreich:", result.data.message);
const rowToRemove = document.getElementById(`machine-row-${machineId}`);
if (rowToRemove) {
const list = rowToRemove.closest('ul');
rowToRemove.remove();
// Optional: Platzhalter wieder einfügen, wenn Liste leer ist
if (list && !list.querySelector('li')) { const placeholder = document.createElement('li'); placeholder.className = 'list-group-item text-muted small ps-0 py-1 no-machines-placeholder'; placeholder.textContent = 'Keine Maschinen (mehr) in dieser Gruppe.'; list.appendChild(placeholder); }
}
} else { throw new Error(result.data.message || 'Fehler beim Löschen der Maschine'); }
})
.catch(error => { console.error("Fehler beim Maschinen-Löschen:", error); alert(`Fehler: ${error.message}`); });
} else { console.log("Löschen der Maschine abgebrochen."); }
}
}); // Ende Klick-Listener für mgmtContainer
// --- Submit-Handler für Gruppen-Bearbeitung ---
function handleEditGroupSubmit(groupId, formElement) {
const formData = new FormData(formElement);
const dataToSend = {
name: formData.get('name'),
abbreviation: formData.get('abbreviation'), // Holt Abkürzung
color: formData.get('color') // Holt Farbe
};
console.log("Sende Update für Gruppe:", groupId, dataToSend);
const submitButton = formElement.querySelector('button[type="submit"]');
if(submitButton) submitButton.disabled = true;
fetch(`/api/group/${groupId}`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(dataToSend) })
.then(response => response.ok ? response.json() : response.json().then(err => Promise.reject(err)))
.then(result => { if(result.status === 'success') { if(modal) modal.style.display = 'none'; window.location.reload(); } else { throw new Error(result.message); } })
.catch(error => { alert(`Fehler: ${error.message}`); if(submitButton) submitButton.disabled = false; });
} // Ende handleEditGroupSubmit
// --- Submit-Handler für Maschinen-Bearbeitung ---
function handleEditMachineSubmit(machineId, formElement) {
const formData = new FormData(formElement);
const groupIdValue = formData.get('group_id');
const dataToSend = { name: formData.get('name'), group_id: (groupIdValue && groupIdValue !== '0') ? groupIdValue : null };
console.log("Sende Update für Maschine:", machineId, dataToSend);
const submitButton = formElement.querySelector('button[type="submit"]');
if(submitButton) submitButton.disabled = true;
fetch(`/api/machine/${machineId}`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(dataToSend) })
.then(response => response.ok ? response.json() : response.json().then(err => Promise.reject(err)))
.then(result => { if(result.status === 'success') { if(modal) modal.style.display = 'none'; window.location.reload(); } else { throw new Error(result.message); } })
.catch(error => { alert(`Fehler: ${error.message}`); if(submitButton) submitButton.disabled = false; });
} // Ende handleEditMachineSubmit
} else {
// Logge, welche Elemente fehlen könnten
console.warn("Schichtplaner JS: Container für Maschinen/Gruppen oder Edit-Vorlagen nicht gefunden.", {mgmtContainer, editGroupFormTemplate, editMachineFormTemplate});
}
// --- ENDE Modul 8: Maschinen & Gruppen ---
// --- Neuer Event-Listener für Interaktionen im Schichtarten-Einstellungs-Modal ---
if (settingsModalElement) { // Prüfe ob das Einstellungs-Modal existiert
console.log("Schichtplaner JS: Initialisiere Edit/Delete Listener für Schichtarten im Einstellungen-Modal.");
// Nutze Event Delegation auf dem Modal-Element selbst
settingsModalElement.addEventListener('click', function(event) {
const targetButton = event.target.closest('button'); // Finde den geklickten Button
if (!targetButton) return; // Ignoriere Klicks, die nicht auf Buttons sind
// --- Schichtart Bearbeiten ---
if (targetButton.classList.contains('edit-shift-type-btn')) {
event.preventDefault(); // Wichtig, falls Button in Formular ist
const shiftTypeId = targetButton.dataset.shiftTypeId;
const modalTitleText = targetButton.dataset.modalTitle; // Titel für das *nächste* (common) Modal
const targetTemplateId = targetButton.dataset.modalTarget; // ID der Edit-Vorlage im HTML
console.log(`Bearbeiten geklickt für Schichtart ID: ${shiftTypeId}`);
// API Call zum Holen der Daten
fetch(`/api/shift_type/${shiftTypeId}`)
.then(response => response.ok ? response.json() : response.json().then(err => Promise.reject(err)))
.then(result => {
if (result.status === 'success' && result.shift_type) {
const stData = result.shift_type;
// Öffne das ALLGEMEINE Modal (#commonModal) mit der Edit-Vorlage für Schichtarten
// Wichtig: targetTemplateId muss die ID der *versteckten* Vorlage sein
openModalGeneric('commonModal', modalTitleText || 'Schichtart bearbeiten', targetTemplateId, 'form');
// Finde das Formular im JETZT geöffneten #commonModal
const visibleEditForm = commonModalBody.querySelector('.edit-shift-type-form');
if(visibleEditForm) {
// Formularfelder füllen (verwende die IDs aus der Vorlage #editShiftTypeFormTemplateModal)
const nameInput = visibleEditForm.querySelector('#st_name_edit_modal');
const abbrInput = visibleEditForm.querySelector('#st_abbr_edit_modal');
const colorInput = visibleEditForm.querySelector('#st_color_edit_modal');
const textColorInput = visibleEditForm.querySelector('#st_textcolor_edit_modal');
const isAbsenceInput = visibleEditForm.querySelector('#st_is_absence_edit_modal');
const hidePrintInput = visibleEditForm.querySelector('#st_hide_on_print_edit_modal');
if(nameInput) nameInput.value = stData.name || '';
if(abbrInput) abbrInput.value = stData.abbreviation || '';
if(colorInput) colorInput.value = stData.color || '#FFFFFF';
if(textColorInput) textColorInput.value = stData.text_color || '#000000';
if(isAbsenceInput) isAbsenceInput.checked = stData.is_absence;
if(hidePrintInput) hidePrintInput.checked = stData.hide_on_print;
// WICHTIG: Submit Listener neu binden (verhindert Mehrfachbindung)
const newForm = visibleEditForm.cloneNode(true);
visibleEditForm.parentNode.replaceChild(newForm, visibleEditForm);
newForm.addEventListener('submit', (e) => {
e.preventDefault();
// Rufe den Submit Handler auf (siehe unten)
handleEditShiftTypeSubmit(shiftTypeId, newForm);
});
} else { console.error("Konnte .edit-shift-type-form im #commonModal nicht finden nach dem Öffnen."); }
} else { throw new Error(result.message || "Fehler Laden Schichtartdaten"); }
})
.catch(error => { console.error("Fehler:", error); alert(`Fehler: ${error.message}`); });
}
// --- Schichtart Löschen ---
else if (targetButton.classList.contains('delete-shift-type-btn')) {
event.preventDefault();
const shiftTypeId = targetButton.dataset.shiftTypeId;
const shiftTypeName = targetButton.dataset.shiftTypeName || 'diese Schichtart';
if (confirm(`Schichtart '${shiftTypeName}' wirklich löschen?`)) {
console.log(`Löschen bestätigt für Schichtart ID: ${shiftTypeId}`);
fetch(`/api/shift_type/${shiftTypeId}`, { method: 'DELETE', headers: { 'Accept': 'application/json' } })
.then(response => response.json().then(data => ({ ok: response.ok, status: response.status, data: data })))
.then(result => {
if (result.ok && result.data && result.data.status === 'success') {
// Entferne Zeile aus der Tabelle im Einstellungs-Modal
const rowToRemove = settingsModalElement.querySelector(`#shift-type-row-modal-${shiftTypeId}`);
if (rowToRemove) {
rowToRemove.remove();
console.log(`Zeile shift-type-row-modal-${shiftTypeId} entfernt.`);
} else {
console.warn(`Zeile shift-type-row-modal-${shiftTypeId} nicht im Modal gefunden.`);
}
} else { throw new Error(result.data.message || `API Fehler ${result.status}`); }
})
.catch(error => { console.error("Fehler:", error); alert(`Fehler beim Löschen: ${error.message}`); });
}
}
// --- HIER KEINE ROLLE MEHR ---
}); // Ende Klick-Listener für Einstellungs-Modal
} else {
console.warn("Schichtplaner JS: Einstellungs-Modal (#shiftTypeSettingsModal) nicht gefunden, kann keine Listener binden.");
}
// --- Submit Handler MÜSSEN außerhalb des if-Blocks definiert sein, ---
// damit sie auch gefunden werden, wenn das Modal geschlossen ist.
// Funktion zum Verarbeiten des Schichtart-Bearbeiten-Formulars
function handleEditShiftTypeSubmit(shiftTypeId, formElement) {
const formData = new FormData(formElement);
const dataToSend = {
name: formData.get('name'),
abbreviation: formData.get('abbreviation'),
color: formData.get('color'),
text_color: formData.get('text_color'),
is_absence: formData.has('is_absence'), // .has prüft ob Checkbox gesendet wurde
hide_on_print: formData.has('hide_on_print')
};
console.log("Sende Update für Schichtart:", shiftTypeId, dataToSend);
const submitButton = formElement.querySelector('button[type="submit"]');
if(submitButton) submitButton.disabled = true;
fetch(`/api/shift_type/${shiftTypeId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(dataToSend) })
.then(response => response.json().then(data => ({ ok: response.ok, data: data })))
.then(result => {
if (result.ok && result.data.status === 'success') {
// Schließe das Bearbeiten-Modal (#commonModal)
if(commonModalElement) commonModalElement.style.display = "none";
// Gib Hinweis statt Reload
alert("Schichtart erfolgreich gespeichert.\n\nDie Änderungen werden im Einstellungs-Modal erst nach dem erneuten Öffnen sichtbar.");
// Alternativ: Versuche Tabelle im Einstellungs-Modal dynamisch zu aktualisieren (komplexer)
} else { throw new Error(result.data.message || `API Fehler`); }
})
.catch(error => { alert(`Fehler beim Speichern: ${error.message}`); if(submitButton) submitButton.disabled = false; });
}
}); // Ende DOMContentLoaded
Please help me!