start rota export in grid format
This commit is contained in:
@@ -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(
|
||||
`<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;
|
||||
|
||||
$("#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 = $(`
|
||||
<details><summary>Shift Timetable Colours</summary>
|
||||
@@ -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 = $(`<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)
|
||||
function rerenderWorkerCheckboxesIfNeeded() {
|
||||
$("#shift-timetable-worker-filter").remove();
|
||||
|
||||
Reference in New Issue
Block a user