start rota export in grid format

This commit is contained in:
Ross
2026-06-03 20:15:34 +01:00
parent e288585cd3
commit ea68885ff3
+125
View File
@@ -1026,6 +1026,7 @@ $("table.tsummary").find("td.prior-adjust .prior-adjust-part").each((n, span) =>
let selectedShifts = new Set(); let selectedShifts = new Set();
let shiftColors = {}; let shiftColors = {};
let rotaExportViewEnabled = false;
oshifts.forEach((shift, i) => { oshifts.forEach((shift, i) => {
selectedShifts.add(shift); selectedShifts.add(shift);
@@ -1038,6 +1039,21 @@ $("#shift-timetable-options").append(
`<button id="toggle-grid-view" style="margin-left:10px;">Toggle Linear/Grid View</button><br/>` `<button id="toggle-grid-view" style="margin-left:10px;">Toggle Linear/Grid View</button><br/>`
); );
// Add a button to toggle rota export view (spreadsheet-style day-by-day shifts)
$("#shift-timetable-options").append(
`<button id="toggle-rota-export-view" style="margin-left:10px;">Show Rota Export View</button>`
);
// Add optional control to show worker names in rota export view
$("#shift-timetable-options").append(`
<span id="rota-export-show-workers-wrap" style="margin-left:12px;">
<label>
<input type="checkbox" id="rota-export-show-workers" checked>
Show workers
</label>
</span><br/>
`);
let gridViewEnabled = false; let gridViewEnabled = false;
$("#toggle-grid-view").on("click", function () { $("#toggle-grid-view").on("click", function () {
@@ -1045,6 +1061,22 @@ $("#toggle-grid-view").on("click", function () {
renderShiftTimetable(); renderShiftTimetable();
}); });
$("#toggle-rota-export-view").on("click", function () {
rotaExportViewEnabled = !rotaExportViewEnabled;
if (rotaExportViewEnabled) {
$(this).text("Show Linear/Grid View");
} else {
$(this).text("Show Rota Export View");
}
renderShiftTimetable();
});
$(document).on("change", "#rota-export-show-workers", function () {
if (rotaExportViewEnabled) {
renderShiftTimetable();
}
});
const shiftColourControls = $(` const shiftColourControls = $(`
<details><summary>Shift Timetable Colours</summary> <details><summary>Shift Timetable Colours</summary>
@@ -1272,6 +1304,12 @@ function renderShiftTimetable() {
console.log(workerFilterSet) console.log(workerFilterSet)
$("#shift-timetable-div").empty(); $("#shift-timetable-div").empty();
if (selectedShifts.size === 0) return; if (selectedShifts.size === 0) return;
if (rotaExportViewEnabled) {
renderRotaExportTimetable();
return;
}
if (workerFilterSet.size === 0) return; if (workerFilterSet.size === 0) return;
// Helper: returns true if worker id matches filter set or set is empty (all) // Helper: returns true if worker id matches filter set or set is empty (all)
@@ -1445,6 +1483,93 @@ function renderShiftTimetable() {
$("#shift-timetable-div").append(gridTable); $("#shift-timetable-div").append(gridTable);
} }
function renderRotaExportTimetable() {
let weeks = [];
let daysOfWeek = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
let weekStartDates = {};
let showWorkers = $("#rota-export-show-workers").is(":checked");
// Build week index and week start dates from existing table data
$("table#main-table td[data-week][data-date]").each(function () {
let week = $(this).attr("data-week");
let date = $(this).attr("data-date");
if (!week || !date) return;
if (!weeks.includes(week)) weeks.push(week);
if (!weekStartDates[week] || new Date(date) < new Date(weekStartDates[week])) {
weekStartDates[week] = date;
}
});
weeks = weeks.sort((a, b) => parseInt(a) - parseInt(b));
let table = $(`<table id="rota-export-table" class="shift-grid-table" style="margin-bottom:20px; border-collapse:collapse; width:auto; table-layout:fixed;"><caption>Rota Export (Shifts by Day)</caption></table>`);
let header = $("<tr><th style='border:1px solid #888; min-width:100px;'>Week</th></tr>");
daysOfWeek.forEach(day => {
header.append(`<th style='border:1px solid #888; min-width:160px;'>${day}</th>`);
});
table.append(header);
weeks.forEach(week => {
let row = $("<tr></tr>");
let weekLabel = `${week}`;
if (showWeekStart && weekStartDates[week]) {
weekLabel += `<div style="font-size:0.85em; color:#444;">${weekStartDates[week]}</div>`;
}
row.append(`<td style='border:1px solid #888; font-weight:bold; vertical-align:top;'>${weekLabel}</td>`);
daysOfWeek.forEach(day => {
let shiftMap = {};
let dayDate = "";
$(`table#main-table td[data-week='${week}'][data-day='${day}']`).each(function () {
let shifts = ($(this).attr("data-shift") || "").split(",").map(s => s.trim()).filter(Boolean);
let date = $(this).attr("data-date") || "";
if (!dayDate && date) dayDate = date;
let workerName = $(this).closest("tr").find("td.worker span.name").text().trim();
shifts.forEach(shift => {
if (!selectedShifts.has(shift)) return;
if (!shiftMap[shift]) {
shiftMap[shift] = new Set();
}
if (workerName) {
shiftMap[shift].add(workerName);
}
});
});
let shiftNames = Object.keys(shiftMap).sort();
if (shiftNames.length === 0) {
let emptyText = dayDate ? `<div style='font-size:0.85em;color:#666;'>${dayDate}</div>-` : "-";
row.append(`<td style='border:1px solid #888; color:#999; text-align:center;'>${emptyText}</td>`);
} else {
let content = [];
if (dayDate) {
content.push(`<div style='font-size:0.8em; color:#555; margin-bottom:4px;'>${dayDate}</div>`);
}
shiftNames.forEach(shift => {
let workerList = Array.from(shiftMap[shift]).sort();
let workerSuffix = "";
if (showWorkers && workerList.length > 0) {
workerSuffix = `: ${workerList.join(" / ")}`;
}
let color = shiftColors[shift] || "#f3f3f3";
content.push(`<div style='background:${color}; margin:2px 0; padding:2px 6px; border-radius:4px; text-align:left;'>${shift}${workerSuffix}</div>`);
});
row.append(`<td style='border:1px solid #888; vertical-align:top;'>${content.join("")}</td>`);
}
});
table.append(row);
});
if (weeks.length === 0) {
table.append(`<tr><td colspan="8" style="border:1px solid #888; text-align:center; color:#666;">No rota data found.</td></tr>`);
}
$("#shift-timetable-div").append(table);
}
// Re-render worker checkboxes after timetable is updated (in case workers change) // Re-render worker checkboxes after timetable is updated (in case workers change)
function rerenderWorkerCheckboxesIfNeeded() { function rerenderWorkerCheckboxesIfNeeded() {
$("#shift-timetable-worker-filter").remove(); $("#shift-timetable-worker-filter").remove();