Add worker filter input to shift timetable and update rendering logic
This commit is contained in:
+82
-70
@@ -494,75 +494,90 @@ function rgb2hex(rgb) {
|
|||||||
return "#ffe066";
|
return "#ffe066";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap timetable rendering in a function so we can call it for both views
|
// Add a worker filter input to the shift timetable section
|
||||||
|
$("#shift-timetable-options").prepend(`
|
||||||
|
<div id="shift-timetable-worker-filter" style="margin-bottom:8px;">
|
||||||
|
<label for="worker-filter-input"><b>Filter workers:</b></label>
|
||||||
|
<input type="text" id="worker-filter-input" placeholder="Type to filter by name..." style="margin-left:4px; padding:2px 6px;"/>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Store the current filter value
|
||||||
|
let workerFilterValue = "";
|
||||||
|
|
||||||
|
// Update the filter value on input
|
||||||
|
$("#worker-filter-input").on("input", function() {
|
||||||
|
workerFilterValue = $(this).val().toLowerCase();
|
||||||
|
renderShiftTimetable();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Patch renderShiftTimetable to filter workers in both linear and grid views
|
||||||
function renderShiftTimetable() {
|
function renderShiftTimetable() {
|
||||||
$("#shift-timetable-div").empty();
|
$("#shift-timetable-div").empty();
|
||||||
if (selectedShifts.size === 0) return;
|
if (selectedShifts.size === 0) return;
|
||||||
|
|
||||||
if (!gridViewEnabled) {
|
// Helper: returns true if worker name matches filter
|
||||||
|
function workerMatchesFilter(workerName) {
|
||||||
// Original (list) view
|
if (!workerFilterValue) return true;
|
||||||
let table = $("<table id='linear-shift-timetable'>");
|
return workerName.toLowerCase().includes(workerFilterValue);
|
||||||
// Add a header row with "Date", "Week", "Day", "Worker"
|
|
||||||
let headerRow = $("<tr>");
|
|
||||||
headerRow.append("<th>Date</th><th>Week</th><th>Day</th><th>Worker(s)</th>");
|
|
||||||
table.append(headerRow);
|
|
||||||
|
|
||||||
$("table#main-table th.date").each((n, th) => {
|
|
||||||
let date = th.dataset.date;
|
|
||||||
// Try to get week and day from the first matching td
|
|
||||||
let week = "";
|
|
||||||
let day = "";
|
|
||||||
let firstTd = $(`table#main-table td[data-date='${date}']`).first();
|
|
||||||
if (firstTd.length) {
|
|
||||||
week = firstTd.attr("data-week") || "";
|
|
||||||
day = firstTd.attr("data-day") || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
let row = $("<tr>");
|
|
||||||
row.append(`<td>${date}</td>`);
|
|
||||||
row.append(`<td>${week}</td>`);
|
|
||||||
row.append(`<td>${day}</td>`);
|
|
||||||
|
|
||||||
// For each worker assigned to a selected shift on this date, add a cell
|
|
||||||
let workerCells = [];
|
|
||||||
$(`table#main-table td[data-date='${date}']`).filter(function () {
|
|
||||||
let shifts = $(this).attr("data-shift");
|
|
||||||
if (!shifts) return false;
|
|
||||||
let cell_shifts = shifts.split(",").map(s => s.trim());
|
|
||||||
// Show if any selected shift is present
|
|
||||||
return Array.from(selectedShifts).some(s => cell_shifts.includes(s));
|
|
||||||
}).each((n, td) => {
|
|
||||||
let workerTd = $(td).closest("tr").children("td:first");
|
|
||||||
let workerName = workerTd.find("span.name").text().trim();
|
|
||||||
// Find which selected shift(s) are present in this cell
|
|
||||||
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";
|
|
||||||
if (matchedShifts.length === 1) {
|
|
||||||
color = shiftColors[matchedShifts[0]];
|
|
||||||
} else if (matchedShifts.length > 1) {
|
|
||||||
// Use a 50/50 split background for two shifts
|
|
||||||
color = `linear-gradient(90deg, ${shiftColors[matchedShifts[0]]} 0 50%, ${shiftColors[matchedShifts[1]]} 50% 100%)`;
|
|
||||||
}
|
|
||||||
workerCells.push(`<td style="background:${color}">${workerName}</td>`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// If no workers, add an empty cell
|
|
||||||
if (workerCells.length === 0) {
|
|
||||||
row.append("<td></td>");
|
|
||||||
} else {
|
|
||||||
// If multiple workers, join their names with commas
|
|
||||||
row.append(workerCells.join(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
table.append(row);
|
|
||||||
});
|
|
||||||
$("#shift-timetable-div").append(table);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Get all weeks and days
|
if (!gridViewEnabled) {
|
||||||
|
// Linear view
|
||||||
|
let table = $("<table id='linear-shift-timetable'>");
|
||||||
|
let headerRow = $("<tr>");
|
||||||
|
headerRow.append("<th>Date</th><th>Week</th><th>Day</th><th>Worker(s)</th>");
|
||||||
|
table.append(headerRow);
|
||||||
|
|
||||||
|
$("table#main-table th.date").each((n, th) => {
|
||||||
|
let date = th.dataset.date;
|
||||||
|
let week = "";
|
||||||
|
let day = "";
|
||||||
|
let firstTd = $(`table#main-table td[data-date='${date}']`).first();
|
||||||
|
if (firstTd.length) {
|
||||||
|
week = firstTd.attr("data-week") || "";
|
||||||
|
day = firstTd.attr("data-day") || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
let row = $("<tr>");
|
||||||
|
row.append(`<td>${date}</td>`);
|
||||||
|
row.append(`<td>${week}</td>`);
|
||||||
|
row.append(`<td>${day}</td>`);
|
||||||
|
|
||||||
|
let workerCells = [];
|
||||||
|
$(`table#main-table td[data-date='${date}']`).filter(function () {
|
||||||
|
let shifts = $(this).attr("data-shift");
|
||||||
|
if (!shifts) return false;
|
||||||
|
let cell_shifts = shifts.split(",").map(s => s.trim());
|
||||||
|
return Array.from(selectedShifts).some(s => cell_shifts.includes(s));
|
||||||
|
}).each((n, td) => {
|
||||||
|
let workerTd = $(td).closest("tr").children("td:first");
|
||||||
|
let workerName = workerTd.find("span.name").text().trim();
|
||||||
|
if (!workerMatchesFilter(workerName)) 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";
|
||||||
|
if (matchedShifts.length === 1) {
|
||||||
|
color = shiftColors[matchedShifts[0]];
|
||||||
|
} else if (matchedShifts.length > 1) {
|
||||||
|
color = `linear-gradient(90deg, ${shiftColors[matchedShifts[0]]} 0 50%, ${shiftColors[matchedShifts[1]]} 50% 100%)`;
|
||||||
|
}
|
||||||
|
workerCells.push(`<td style="background:${color}">${workerName}</td>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (workerCells.length === 0) {
|
||||||
|
row.append("<td></td>");
|
||||||
|
} else {
|
||||||
|
row.append(workerCells.join(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
table.append(row);
|
||||||
|
});
|
||||||
|
$("#shift-timetable-div").append(table);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid view
|
||||||
let weeks = [];
|
let weeks = [];
|
||||||
let daysOfWeek = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
let daysOfWeek = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
||||||
$("table#main-table td[data-week]").each(function () {
|
$("table#main-table td[data-week]").each(function () {
|
||||||
@@ -571,20 +586,19 @@ function renderShiftTimetable() {
|
|||||||
});
|
});
|
||||||
weeks = weeks.sort((a, b) => parseInt(a) - parseInt(b));
|
weeks = weeks.sort((a, b) => parseInt(a) - parseInt(b));
|
||||||
|
|
||||||
|
|
||||||
// Get all workers who have at least one selected shift
|
|
||||||
let workerIds = [];
|
let workerIds = [];
|
||||||
let workerIdToName = {};
|
let workerIdToName = {};
|
||||||
$("table#main-table td.worker").each(function () {
|
$("table#main-table td.worker").each(function () {
|
||||||
let workerId = $(this).attr("data-worker-id");
|
let workerId = $(this).attr("data-worker-id");
|
||||||
if (workerId && !workerIds.includes(workerId)) {
|
if (workerId && !workerIds.includes(workerId)) {
|
||||||
workerIds.push(workerId);
|
|
||||||
let workerName = $(this).find("span.name").text().trim();
|
let workerName = $(this).find("span.name").text().trim();
|
||||||
workerIdToName[workerId] = workerName;
|
if (workerMatchesFilter(workerName)) {
|
||||||
|
workerIds.push(workerId);
|
||||||
|
workerIdToName[workerId] = workerName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// workerId -> week -> day -> {shifts: [...], name: ...}
|
|
||||||
let cellMap = {};
|
let cellMap = {};
|
||||||
$("table#main-table td.worker").each(function () {
|
$("table#main-table td.worker").each(function () {
|
||||||
let workerId = $(this).attr("data-worker-id");
|
let workerId = $(this).attr("data-worker-id");
|
||||||
@@ -634,8 +648,6 @@ function renderShiftTimetable() {
|
|||||||
gridTable.append(row);
|
gridTable.append(row);
|
||||||
});
|
});
|
||||||
$("#shift-timetable-div").append(gridTable);
|
$("#shift-timetable-div").append(gridTable);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch the timetable button logic to use renderShiftTimetable
|
// Patch the timetable button logic to use renderShiftTimetable
|
||||||
|
|||||||
Reference in New Issue
Block a user