From a423e0696b6d4768a11221439c40f2cbe461f3e7 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Thu, 19 Mar 2026 20:47:59 -0700 Subject: [PATCH] fix(schedule): correct tall view rendering for reservations with hidden blocked periods When a reservation ends in a hidden blocked period, the exact end cell doesn't exist in the DOM and findClosestEnd() picks the nearest earlier slot. This caused two issues in ScheduleTall view: 1. The reservation div height was too short because it only reached the top of the last visible slot instead of extending through its bottom. 2. The div's data-start/data-end attributes used the approximate cell's data-min value instead of the reservation's actual timestamps, which could cause conflict detection to miss overlapping reservations. Fix by introducing an isEndApproximate flag to add the missing slot height, and by using res.StartDate/res.EndDate directly for data attributes on reservation and buffer divs. Closes: #920 --- Web/scripts/schedule.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Web/scripts/schedule.js b/Web/scripts/schedule.js index 8d587f62a..af768ebe9 100644 --- a/Web/scripts/schedule.js +++ b/Web/scripts/schedule.js @@ -191,6 +191,9 @@ function Schedule(opts, resourceGroups) { 'td[data-resourceid="' + res.ResourceId + '"][data-min="' + res[endAttribute] + '"]:first' ); let calculatedAdjustment = 0; + // true when the exact end cell is missing (e.g. hidden blocked period) + // and findClosestEnd() picked the nearest earlier slot instead + let isEndApproximate = false; if (startTd.length === 0) { startTd = findClosestStart(table.find('td[data-resourceid="' + res.ResourceId + '"]'), res, startAttribute); @@ -198,6 +201,7 @@ function Schedule(opts, resourceGroups) { if (endTd.length === 0) { endTd = findClosestEnd(table.find('td[data-resourceid="' + res.ResourceId + '"]'), res, endAttribute); calculatedAdjustment = endTd.outerWidth(); + isEndApproximate = true; } if (startTd.length === 0 || endTd.length === 0) { // does not fit in this reservation table @@ -212,6 +216,11 @@ function Schedule(opts, resourceGroups) { if (opts.scheduleStyle === ScheduleTall) { width = startTd.outerWidth() - cellAdjustment; height = endTd.position().top - startTd.position().top; + if (isEndApproximate && height > 0) { + // findClosestEnd was used: endTd is the last slot STARTING before resEnd, + // but height must extend through to the bottom of that slot row + height += endTd.outerHeight(); + } top = startTd.position().top; left += cellAdjustment; } @@ -666,8 +675,8 @@ function Schedule(opts, resourceGroups) { style="${style} ${color}" data-resid="${res.ReferenceNumber}" data-resourceid="${res.ResourceId}" - data-start="${startTd.data('min')}" - data-end="${endTd.data('min')}" + data-start="${res.StartDate}" + data-end="${res.EndDate}" ${draggableAttribute}>${isNew} ${isUpdated} ${res.Label}`); if (res.IsReservation) { @@ -702,8 +711,8 @@ function Schedule(opts, resourceGroups) { style="${style}" data-resid="${res.ReferenceNumber}" data-resourceid="${res.ResourceId}" - data-start="${startTd.data('min')}" - data-end="${endTd.data('min')}"> `); + data-start="${res.BufferedStartDate}" + data-end="${res.BufferedEndDate}"> `); t.append(bufferDiv); } }