diff --git a/output/timetable.js b/output/timetable.js
index bfe18eb..f86b3ae 100644
--- a/output/timetable.js
+++ b/output/timetable.js
@@ -1026,6 +1026,7 @@ $("table.tsummary").find("td.prior-adjust .prior-adjust-part").each((n, span) =>
let selectedShifts = new Set();
let shiftColors = {};
+let rotaExportViewEnabled = false;
oshifts.forEach((shift, i) => {
selectedShifts.add(shift);
@@ -1038,6 +1039,21 @@ $("#shift-timetable-options").append(
`Toggle Linear/Grid View `
);
+// Add a button to toggle rota export view (spreadsheet-style day-by-day shifts)
+$("#shift-timetable-options").append(
+ `Show Rota Export View `
+);
+
+// Add optional control to show worker names in rota export view
+$("#shift-timetable-options").append(`
+
+
+
+ Show workers
+
+
+`);
+
let gridViewEnabled = false;
$("#toggle-grid-view").on("click", function () {
@@ -1045,6 +1061,22 @@ $("#toggle-grid-view").on("click", function () {
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 = $(`
Shift Timetable Colours
@@ -1272,6 +1304,12 @@ function renderShiftTimetable() {
console.log(workerFilterSet)
$("#shift-timetable-div").empty();
if (selectedShifts.size === 0) return;
+
+ if (rotaExportViewEnabled) {
+ renderRotaExportTimetable();
+ return;
+ }
+
if (workerFilterSet.size === 0) return;
// 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);
}
+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 = $(`Rota Export (Shifts by Day)
`);
+ let header = $("Week ");
+ daysOfWeek.forEach(day => {
+ header.append(`${day} `);
+ });
+ table.append(header);
+
+ weeks.forEach(week => {
+ let row = $(" ");
+ let weekLabel = `${week}`;
+ if (showWeekStart && weekStartDates[week]) {
+ weekLabel += `${weekStartDates[week]}
`;
+ }
+ row.append(`${weekLabel} `);
+
+ 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 ? `${dayDate}
-` : "-";
+ row.append(`${emptyText} `);
+ } else {
+ let content = [];
+ if (dayDate) {
+ content.push(`${dayDate}
`);
+ }
+ 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(`${shift}${workerSuffix}
`);
+ });
+ row.append(`${content.join("")} `);
+ }
+ });
+
+ table.append(row);
+ });
+
+ if (weeks.length === 0) {
+ table.append(`No rota data found. `);
+ }
+
+ $("#shift-timetable-div").append(table);
+}
+
// Re-render worker checkboxes after timetable is updated (in case workers change)
function rerenderWorkerCheckboxesIfNeeded() {
$("#shift-timetable-worker-filter").remove();