@@ -25,9 +25,6 @@ import {
2525import {
2626 initAndUpdateTimeTableConfigStore ,
2727 type TimeFrameDay ,
28- useTTCSlotsArray ,
29- useTTCTimeFrameOfDay ,
30- useTTCTimeSlotMinutes ,
3128} from "./TimeTableConfigStore"
3229import { TimeTableIdentProvider } from "./TimeTableIdentContext"
3330import { initAndUpdateTimeTableComponentStore } from "./TimeTableComponentStore"
@@ -194,6 +191,12 @@ export interface LPTimeTableProps<
194191 timeSlot : ( props : CustomHeaderRowTimeSlotProps < G , I > ) => JSX . Element
195192 header : ( props : CustomHeaderRowHeaderProps < G , I > ) => JSX . Element
196193 }
194+
195+ /**
196+ * renderBatch tells how many groups are calculated in one step and rendered. This is useful for large time tables, where the rendering takes a long time.
197+ * @default 10
198+ */
199+ renderBatch ?: number
197200}
198201
199202const nowbarUpdateIntervall = 1000 * 60 // 1 minute
@@ -214,6 +217,8 @@ export default function LPTimeTable<
214217 )
215218}
216219
220+ export let timeTableGroupRenderBatchSize = 10
221+
217222/**
218223 * The LPTimeTable depends on the localization messages. It needs to be wrapped in an
219224 * @returns
@@ -252,12 +257,15 @@ const LPTimeTableImpl = <G extends TimeTableGroup, I extends TimeSlotBooking>({
252257 className,
253258 style,
254259 customHeaderRow,
260+ renderBatch = timeTableGroupRenderBatchSize ,
255261} : LPTimeTableProps < G , I > ) => {
256262 // if we have viewType of days, we need to round the start and end date to the start and end of the day
257263 const { setMessage, translatedMessage } = useTimeTableMessage (
258264 ! disableMessages ,
259265 )
260266
267+ timeTableGroupRenderBatchSize = renderBatch
268+
261269 // change on viewType
262270 // biome-ignore lint/correctness/useExhaustiveDependencies: just remove the message is props change
263271 useEffect ( ( ) => {
@@ -293,33 +301,32 @@ const LPTimeTableImpl = <G extends TimeTableGroup, I extends TimeSlotBooking>({
293301 isCellDisabled ,
294302 )
295303
296- const timeFrameDay = useTTCTimeFrameOfDay ( storeIdent )
297- const timeSlotMinutes = useTTCTimeSlotMinutes ( storeIdent )
298-
299304 initAndUpdateTimeTableSelectionStore (
300305 storeIdent ,
301306 defaultSelectedTimeRange ,
302307 selectedTimeRange ,
303308 onTimeRangeSelected ,
304309 )
305310
306- const slotsArray = useTTCSlotsArray ( storeIdent )
307- if ( ! slotsArray || slotsArray . length === 0 ) {
308- console . warn (
309- "LPTimeTable - no slots array, or slots array is empty" ,
310- slotsArray ,
311- )
312- return < div > No slots array</ div >
313- }
314-
315311 const {
316312 groupRows,
317313 rowCount,
318314 maxRowCountOfSingleGroup,
319315 itemsOutsideOfDayRange,
320316 itemsWithSameStartAndEnd,
317+ slotsArray,
318+ timeFrameDay,
319+ timeSlotMinutes,
321320 } = useGroupRows ( entries )
322321
322+ if ( ! slotsArray || slotsArray . length === 0 ) {
323+ console . warn (
324+ "LPTimeTable - no slots array, or slots array is empty" ,
325+ slotsArray ,
326+ )
327+ return < div > No slots array</ div >
328+ }
329+
323330 useEffect ( ( ) => {
324331 if ( ! setMessage ) return
325332 if ( Object . keys ( itemsOutsideOfDayRange ) . length > 0 ) {
@@ -531,6 +538,10 @@ const LPTimeTableImpl = <G extends TimeTableGroup, I extends TimeSlotBooking>({
531538 intersectionContainerRef
532539 }
533540 headerRef = { tableHeaderRef }
541+ slotsArray = { slotsArray }
542+ timeSlotMinutes = { timeSlotMinutes }
543+ timeFrameDay = { timeFrameDay }
544+ viewType = { viewType }
534545 />
535546 </ tbody >
536547 </ table >
@@ -627,11 +638,27 @@ function moveNowBar(
627638 const startSlot = startAndEndSlot . startSlot
628639
629640 // the first row in the body is used for the time slot bars
630- const tbodyFirstRow = tableBody . children [ 0 ] as
641+ let childIdx = 0
642+ let tbodyFirstRow = tableBody . children [ childIdx ] as
631643 | HTMLTableRowElement
632644 | undefined
633645 // now get the current time slot index element (not -1 because the first empty element for the groups)
634646
647+ // find the first rendered row
648+ while ( tbodyFirstRow && tbodyFirstRow . children . length === 0 ) {
649+ childIdx ++
650+ tbodyFirstRow = tableBody . children [ childIdx ] as
651+ | HTMLTableRowElement
652+ | undefined
653+ }
654+
655+ if ( ! tbodyFirstRow ) {
656+ console . warn (
657+ "LPTimeTable - unable to find time slot row for the now bar" ,
658+ )
659+ return
660+ }
661+
635662 const slotBar = tbodyFirstRow ?. children [ startSlot + 1 ] as
636663 | HTMLDivElement
637664 | undefined
@@ -652,7 +679,7 @@ function moveNowBar(
652679 nowBar = document . createElement ( "div" )
653680 //nowBar.className = styles.nowBar
654681 nowBar . className =
655- "absolute opacity-60 bg-orange-bold top-0 bottom-0 z-[1 ] w-[2px]"
682+ "absolute opacity-60 bg-orange-bold top-0 bottom-0 z-[2 ] w-[2px]"
656683 slotBar . appendChild ( nowBar )
657684 nowBarRef . current = nowBar
658685 }
@@ -673,7 +700,7 @@ function moveNowBar(
673700
674701 const diffPerc = diffNow / timeSlotMinutes
675702 nowBar . style . left = `${ diffPerc * 100 } %`
676- nowBar . style . height = `${ tableBody . clientHeight } px`
703+ nowBar . style . height = `${ tableBody . getBoundingClientRect ( ) . bottom - slotBar . getBoundingClientRect ( ) . top } px`
677704
678705 // add orange border
679706 const nowTimeSlotCell = headerTimeSlotCells [ startSlot + 1 ]
0 commit comments