@@ -558,7 +559,15 @@ $("#shift-timetable-options").prepend(`
Show shift names in timetable
+`).prepend(`
+
+
+
`);
+
// Add a button to remove all shift timetable colours (set to white)
$("#shift-colour-controls").append(
``
@@ -581,6 +590,12 @@ $("#show-shift-names-checkbox").on("change", function() {
renderShiftTimetable();
});
+
+$("#show-week-start-checkbox").on("change", function () {
+ showWeekStart = $(this).is(":checked");
+ renderShiftTimetable();
+});
+
// Patch renderShiftTimetable to show shift names if enabled
function renderShiftTimetable() {
console.log("Render shift timetable");
@@ -663,6 +678,18 @@ function renderShiftTimetable() {
});
weeks = weeks.sort((a, b) => parseInt(a) - parseInt(b));
+
+ // Build week -> start date map (earliest date in that week)
+ let weekStartDates = {};
+ $("table#main-table td[data-week][data-date]").each(function () {
+ let wk = $(this).attr("data-week");
+ let d = $(this).attr("data-date");
+ if (!wk || !d) return;
+ if (!weekStartDates[wk] || new Date(d) < new Date(weekStartDates[wk])) {
+ weekStartDates[wk] = d;
+ }
+ });
+
let workerIds = [];
let workerIdToName = {};
$("table#main-table td.worker").each(function () {
@@ -703,9 +730,14 @@ function renderShiftTimetable() {
weeks.forEach(week => {
let row = $(`
`);
- row.append(`
${week}
`);
+ // Show week number and (optionally) the week's start date
+ let weekLabel = [week];
+ if (showWeekStart && weekStartDates[week]) {
+ weekLabel += `
${weekStartDates[week]}
`;
+ }
+ row.append(`
${weekLabel}
`);
daysOfWeek.forEach(day => {
- let cellContent = "";
+ let cellContent = [];
for (const workerId of workerIds) {
let worker = cellMap[workerId];
let shifts = (worker.cells[week] && worker.cells[week][day]) || [];
@@ -720,10 +752,10 @@ function renderShiftTimetable() {
color = `linear-gradient(90deg, ${shiftColors[matchedShifts[0]]} 0 50%, ${shiftColors[matchedShifts[1]]} 50% 100%)`;
if (showShiftNames) shiftLabel = ` (${matchedShifts.join(", ")})`;
}
- cellContent += `
${worker.name}${shiftLabel}
`;
+ cellContent.push(`
${worker.name}${shiftLabel}
`);
}
}
- row.append(`
${cellContent}
`);
+ row.append(`
${cellContent.join(" / ")}
`);
});
gridTable.append(row);
});
diff --git a/rota/shifts.py b/rota/shifts.py
index 6fd9b85..37373a3 100644
--- a/rota/shifts.py
+++ b/rota/shifts.py
@@ -93,11 +93,13 @@ class PreShiftConstraint(BaseShiftConstraint):
days: Any = None
ignore_shifts: List[str] = []
exclude_days: List[str] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+ allow_self: bool = True
class PostShiftConstraint(BaseShiftConstraint):
days: Any = None
ignore_shifts: List[str] = []
exclude_days: List[str] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+ allow_self: bool = True
class BalanceAcrossGroupsConstraint(BaseShiftConstraint):
""""""
@@ -2932,7 +2934,10 @@ class RotaBuilder(object):
PreShiftConstraint
):
constraint = constraint_shift.get_constraint(PreShiftConstraint)
- ignore_shifts = constraint.ignore_shifts + [constraint_shift.name]
+ if constraint.allow_self:
+ ignore_shifts = constraint.ignore_shifts + [constraint_shift.name]
+ else:
+ ignore_shifts = constraint.ignore_shifts
if week not in constraint.weeks:
continue
for n in range(0, constraint.days):
@@ -2969,7 +2974,10 @@ class RotaBuilder(object):
PostShiftConstraint
):
constraint = constraint_shift.get_constraint(PostShiftConstraint)
- ignore_shifts = constraint.ignore_shifts + [constraint_shift.name]
+ if constraint.allow_self:
+ ignore_shifts = constraint.ignore_shifts + [constraint_shift.name]
+ else:
+ ignore_shifts = constraint.ignore_shifts
if week not in constraint.weeks:
continue
for n in range(0, constraint.days):