diff --git a/output/timetable.js b/output/timetable.js index e3e5bb1..d959feb 100644 --- a/output/timetable.js +++ b/output/timetable.js @@ -382,17 +382,6 @@ oshifts.forEach((shift, i) => { $("#shift-timetable-options").append( `
` ); -// Add help text to the shift timetable section -$("#shift-timetable-options").prepend(` -
- Shift Timetables Help: - -
-`); let gridViewEnabled = false; @@ -494,32 +483,83 @@ function rgb2hex(rgb) { return "#ffe066"; } -// Add a worker filter input to the shift timetable section -$("#shift-timetable-options").prepend(` -
- - -
-`); +// --- Add worker checkboxes to the shift timetable section --- +function renderWorkerCheckboxes() { + // Get all unique worker names and IDs from the main table + let workerList = []; + $("table#main-table td.worker").each(function () { + let workerId = $(this).attr("data-worker-id"); + let workerName = $(this).find("span.name").text().trim(); + if (workerId && !workerList.some(w => w.id === workerId)) { + workerList.push({ id: workerId, name: workerName }); + } + }); -// Store the current filter value -let workerFilterValue = ""; + // Build checkboxes + let html = `
+ Show workers:`; + // Add a "Toggle All" button + html += ``; -// Update the filter value on input -$("#worker-filter-input").on("input", function() { - workerFilterValue = $(this).val().toLowerCase(); + workerList.forEach(w => { + html += ``; + }); + + // Attach toggle logic after DOM insertion + setTimeout(() => { + $("#toggle-all-workers").off("click").on("click", function() { + const $checkboxes = $("input[name='worker-filter-checkbox']"); + const allChecked = $checkboxes.length === $checkboxes.filter(":checked").length; + $checkboxes.prop("checked", !allChecked); + // Update the filter set and re-render once, instead of triggering "change" for each + workerFilterSet = new Set( + Array.from(document.querySelectorAll("input[name='worker-filter-checkbox']:checked")) + .map(cb => cb.value) + ); + // Call your function here after the map has finished + renderShiftTimetable(); + }); + }, 0); + html += `
`; + + // Prepend to the shift timetable options + $("#shift-timetable-options").prepend(html); +} + +// Store the current filter value (set of workerIds) +let workerFilterSet = new Set(); + +// Call this after the DOM is ready and after timetable is rendered +renderWorkerCheckboxes(); + +// On first render, select all workers by default +$("input[name='worker-filter-checkbox']").each(function() { + workerFilterSet.add($(this).val()); +}); +renderShiftTimetable(); + +// Update the filter set on checkbox change +$(document).on("change", "input[name='worker-filter-checkbox']", function() { + workerFilterSet = new Set( + $("input[name='worker-filter-checkbox']:checked").map(function() { return $(this).val(); }).get() + ); renderShiftTimetable(); }); // Patch renderShiftTimetable to filter workers in both linear and grid views function renderShiftTimetable() { + console.log("Render shift timetable"); + console.log(workerFilterSet) $("#shift-timetable-div").empty(); if (selectedShifts.size === 0) return; + if (workerFilterSet.size === 0) return; - // Helper: returns true if worker name matches filter - function workerMatchesFilter(workerName) { - if (!workerFilterValue) return true; - return workerName.toLowerCase().includes(workerFilterValue); + // Helper: returns true if worker id matches filter set or set is empty (all) + function workerMatchesFilter(workerId) { + if (workerFilterSet.size === 0) return true; + return workerFilterSet.has(workerId); } if (!gridViewEnabled) { @@ -553,7 +593,8 @@ function renderShiftTimetable() { }).each((n, td) => { let workerTd = $(td).closest("tr").children("td:first"); let workerName = workerTd.find("span.name").text().trim(); - if (!workerMatchesFilter(workerName)) return; + let workerId = workerTd.attr("data-worker-id"); + if (!workerMatchesFilter(workerId)) return; let cell_shifts = $(td).attr("data-shift").split(",").map(s => s.trim()); let matchedShifts = Array.from(selectedShifts).filter(s => cell_shifts.includes(s)); let color = "#fff"; @@ -590,9 +631,9 @@ function renderShiftTimetable() { let workerIdToName = {}; $("table#main-table td.worker").each(function () { let workerId = $(this).attr("data-worker-id"); + let workerName = $(this).find("span.name").text().trim(); if (workerId && !workerIds.includes(workerId)) { - let workerName = $(this).find("span.name").text().trim(); - if (workerMatchesFilter(workerName)) { + if (workerMatchesFilter(workerId)) { workerIds.push(workerId); workerIdToName[workerId] = workerName; } @@ -650,6 +691,21 @@ function renderShiftTimetable() { $("#shift-timetable-div").append(gridTable); } +// Re-render worker checkboxes after timetable is updated (in case workers change) +function rerenderWorkerCheckboxesIfNeeded() { + $("#shift-timetable-worker-filter").remove(); + renderWorkerCheckboxes(); + // Restore checked state + $("input[name='worker-filter-checkbox']").each(function() { + if (workerFilterSet.has($(this).val())) { + $(this).prop("checked", true); + } + }); +} + +// Call this after timetable is (re)rendered if needed +rerenderWorkerCheckboxesIfNeeded(); + // Patch the timetable button logic to use renderShiftTimetable oshifts.forEach((shift) => { let button = $(``); @@ -676,6 +732,19 @@ oshifts.forEach((shift) => { $("#shift-timetable-options").append(button); }); + + +// Add help text to the shift timetable section +$("#shift-timetable-options").prepend(` +
+ Shift Timetables Help: + +
+`); //$("table.summary") // $("body").prepend("
Settings:
Customise training days lost per shift (you need to press recalculate for changes to take effect)
")