diff --git a/apps/client/src/common/utils/lazyEvaluate.ts b/apps/client/src/common/utils/lazyEvaluate.ts new file mode 100644 index 000000000..69fff5d70 --- /dev/null +++ b/apps/client/src/common/utils/lazyEvaluate.ts @@ -0,0 +1,12 @@ +/** + * Allows lazy evaluation and caching of a functions result + */ +export function lazyEvaluate(fn: () => T): () => T { + let result: T | undefined; + return function () { + if (result === undefined) { + result = fn(); + } + return result; + }; +} diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx index 9fac1f1b6..a9ca6fd6d 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx @@ -1,4 +1,4 @@ -import { memo } from 'react'; +import { memo, useRef } from 'react'; import { useCurrentBlockId } from '../../../../common/hooks/useSocket'; @@ -7,21 +7,37 @@ import style from '../CuesheetTable.module.scss'; interface BlockRowProps { hidePast: boolean; title: string; + columnCount: number; } function BlockRow(props: BlockRowProps) { - const { hidePast, title } = props; + const { hidePast, title, columnCount } = props; const { currentBlockId } = useCurrentBlockId(); + const firstCellRef = useRef(null); if (hidePast && !currentBlockId) { return null; } + const paddingRows = new Array(columnCount - 1).fill(null); + return ( - + {title} + {paddingRows.map((_value, index) => { + return ( + { + firstCellRef.current?.focus(); + }} + /> + ); + })} ); } diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetBody.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetBody.tsx index d5ed7a3f8..c7171a75f 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetBody.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetBody.tsx @@ -4,6 +4,7 @@ import Color from 'color'; import { isOntimeBlock, isOntimeDelay, isOntimeEvent, OntimeRundownEntry } from 'ontime-types'; import { useSelectedEventId } from '../../../../common/hooks/useSocket'; +import { lazyEvaluate } from '../../../../common/utils/lazyEvaluate'; import { getAccessibleColour } from '../../../../common/utils/styleUtils'; import { useCuesheetOptions } from '../../../cuesheet/cuesheet.options'; @@ -24,6 +25,8 @@ export default function CuesheetBody(props: CuesheetBodyProps) { const { selectedEventId } = useSelectedEventId(); const { hideDelays, hidePast } = useCuesheetOptions(); + const getColumnCount = lazyEvaluate(() => table.getVisibleFlatColumns().length); + let eventIndex = 0; // for the first event, it will be past if there is something selected let isPast = Boolean(selectedEventId); @@ -38,7 +41,8 @@ export default function CuesheetBody(props: CuesheetBodyProps) { } if (isOntimeBlock(entry)) { - return ; + const columnCount = getColumnCount(); + return ; } if (isOntimeDelay(entry)) { if (isPast && hidePast) {