refactor: restructure model to contain an object of rundowns

This commit is contained in:
Carlos Valente
2025-03-15 09:04:33 +01:00
committed by arc-alex
parent 0a80d6db31
commit abd9b127db
111 changed files with 4357 additions and 4515 deletions
@@ -8,7 +8,7 @@ import {
useRef,
useState,
} from 'react';
import { isOntimeEvent, OntimeEvent, OntimeRundownEntry } from 'ontime-types';
import { isOntimeEvent, OntimeEntry, OntimeEvent } from 'ontime-types';
import { usePartialRundown } from '../../../common/hooks-query/useRundown';
@@ -36,7 +36,7 @@ export const ScheduleProvider = ({
isBackstage = false,
}: PropsWithChildren<ScheduleProviderProps>) => {
const { cycleInterval, stopCycle } = useScheduleOptions();
const { data: events } = usePartialRundown((event: OntimeRundownEntry) => {
const { data: events } = usePartialRundown((event: OntimeEntry) => {
if (isBackstage) {
return isOntimeEvent(event);
}
@@ -9,12 +9,12 @@ import {
useSensors,
} from '@dnd-kit/core';
import { ColumnDef } from '@tanstack/react-table';
import { OntimeRundownEntry } from 'ontime-types';
import { OntimeEntry } from 'ontime-types';
import useColumnManager from '../cuesheet-table/useColumnManager';
interface CuesheetDndProps {
columns: ColumnDef<OntimeRundownEntry>[];
columns: ColumnDef<OntimeEntry>[];
}
export default function CuesheetDnd(props: PropsWithChildren<CuesheetDndProps>) {
@@ -1,7 +1,7 @@
import { useCallback, useRef } from 'react';
import { useTableNav } from '@table-nav/react';
import { ColumnDef, getCoreRowModel, useReactTable } from '@tanstack/react-table';
import { isOntimeEvent, MaybeString, OntimeEvent, OntimeRundown, OntimeRundownEntry, TimeField } from 'ontime-types';
import { isOntimeEvent, MaybeString, OntimeEntry, OntimeEvent, TimeField } from 'ontime-types';
import { useEventAction } from '../../../common/hooks/useEventAction';
import useFollowComponent from '../../../common/hooks/useFollowComponent';
@@ -16,8 +16,8 @@ import useColumnManager from './useColumnManager';
import style from './CuesheetTable.module.scss';
interface CuesheetTableProps {
data: OntimeRundown;
columns: ColumnDef<OntimeRundownEntry>[];
data: OntimeEntry[];
columns: ColumnDef<OntimeEntry>[];
showModal: (eventId: MaybeString) => void;
}
@@ -1,7 +1,7 @@
import { MutableRefObject } from 'react';
import { RowModel, Table } from '@tanstack/react-table';
import Color from 'color';
import { isOntimeBlock, isOntimeDelay, isOntimeEvent, OntimeRundownEntry } from 'ontime-types';
import { isOntimeBlock, isOntimeDelay, isOntimeEvent, OntimeEntry } from 'ontime-types';
import { useSelectedEventId } from '../../../../common/hooks/useSocket';
import { lazyEvaluate } from '../../../../common/utils/lazyEvaluate';
@@ -13,9 +13,9 @@ import DelayRow from './DelayRow';
import EventRow from './EventRow';
interface CuesheetBodyProps {
rowModel: RowModel<OntimeRundownEntry>;
rowModel: RowModel<OntimeEntry>;
selectedRef: MutableRefObject<HTMLTableRowElement | null>;
table: Table<OntimeRundownEntry>;
table: Table<OntimeEntry>;
}
export default function CuesheetBody(props: CuesheetBodyProps) {
@@ -1,6 +1,6 @@
import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable';
import { flexRender, HeaderGroup } from '@tanstack/react-table';
import { OntimeRundownEntry } from 'ontime-types';
import { OntimeEntry } from 'ontime-types';
import { getAccessibleColour } from '../../../../common/utils/styleUtils';
import { useCuesheetOptions } from '../../cuesheet.options';
@@ -10,7 +10,7 @@ import { SortableCell } from './SortableCell';
import style from '../CuesheetTable.module.scss';
interface CuesheetHeaderProps {
headerGroups: HeaderGroup<OntimeRundownEntry>[];
headerGroups: HeaderGroup<OntimeEntry>[];
}
export default function CuesheetHeader(props: CuesheetHeaderProps) {
@@ -2,7 +2,7 @@ import { memo, MutableRefObject, useLayoutEffect, useRef, useState } from 'react
import { IoEllipsisHorizontal } from 'react-icons/io5';
import { flexRender, Table } from '@tanstack/react-table';
import Color from 'color';
import { OntimeEvent, OntimeRundownEntry } from 'ontime-types';
import { OntimeEntry, OntimeEvent } from 'ontime-types';
import IconButton from '../../../../common/components/buttons/IconButton';
import { cx, getAccessibleColour } from '../../../../common/utils/styleUtils';
@@ -21,7 +21,7 @@ interface EventRowProps {
skip?: boolean;
colour?: string;
rowBgColour?: string;
table: Table<OntimeRundownEntry>;
table: Table<OntimeEntry>;
/** hack to force re-rendering of the row when the column sizes change */
columnHash: string;
}
@@ -2,12 +2,12 @@ import { CSSProperties, ReactNode } from 'react';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Header } from '@tanstack/react-table';
import { OntimeRundownEntry } from 'ontime-types';
import { OntimeEntry } from 'ontime-types';
import styles from '../CuesheetTable.module.scss';
interface SortableCellProps {
header: Header<OntimeRundownEntry, unknown>;
header: Header<OntimeEntry, unknown>;
style: CSSProperties;
children: ReactNode;
}
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { CellContext, ColumnDef } from '@tanstack/react-table';
import { CustomFields, isOntimeEvent, OntimeEvent, OntimeRundownEntry, TimeStrategy } from 'ontime-types';
import { CustomFields, isOntimeEvent, OntimeEntry, OntimeEvent, TimeStrategy } from 'ontime-types';
import { millisToString, removeSeconds } from 'ontime-utils';
import DelayIndicator from '../../../../common/components/delay-indicator/DelayIndicator';
@@ -11,7 +11,7 @@ import MultiLineCell from './MultiLineCell';
import SingleLineCell from './SingleLineCell';
import TimeInput from './TimeInput';
function MakeStart({ getValue, row, table }: CellContext<OntimeRundownEntry, unknown>) {
function MakeStart({ getValue, row, table }: CellContext<OntimeEntry, unknown>) {
if (!table.options.meta) {
return null;
}
@@ -39,7 +39,7 @@ function MakeStart({ getValue, row, table }: CellContext<OntimeRundownEntry, unk
);
}
function MakeEnd({ getValue, row, table }: CellContext<OntimeRundownEntry, unknown>) {
function MakeEnd({ getValue, row, table }: CellContext<OntimeEntry, unknown>) {
if (!table.options.meta) {
return null;
}
@@ -67,7 +67,7 @@ function MakeEnd({ getValue, row, table }: CellContext<OntimeRundownEntry, unkno
);
}
function MakeDuration({ getValue, row, table }: CellContext<OntimeRundownEntry, unknown>) {
function MakeDuration({ getValue, row, table }: CellContext<OntimeEntry, unknown>) {
if (!table.options.meta) {
return null;
}
@@ -87,7 +87,7 @@ function MakeDuration({ getValue, row, table }: CellContext<OntimeRundownEntry,
);
}
function MakeMultiLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
function MakeMultiLineField({ row, column, table }: CellContext<OntimeEntry, unknown>) {
const update = useCallback(
(newValue: string) => {
table.options.meta?.handleUpdate(row.index, column.id, newValue, false);
@@ -101,12 +101,12 @@ function MakeMultiLineField({ row, column, table }: CellContext<OntimeRundownEnt
return null;
}
const initialValue = event[column.id as keyof OntimeRundownEntry] ?? '';
const initialValue = event[column.id as keyof OntimeEntry] ?? '';
return <MultiLineCell initialValue={initialValue} handleUpdate={update} />;
return <MultiLineCell initialValue={initialValue as string} handleUpdate={update} />;
}
function LazyImage({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
function LazyImage({ row, column, table }: CellContext<OntimeEntry, unknown>) {
const update = useCallback(
(newValue: string) => {
table.options.meta?.handleUpdate(row.index, column.id, newValue, true);
@@ -124,7 +124,7 @@ function LazyImage({ row, column, table }: CellContext<OntimeRundownEntry, unkno
return <EditableImage initialValue={initialValue} updateValue={update} />;
}
function MakeSingleLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
function MakeSingleLineField({ row, column, table }: CellContext<OntimeEntry, unknown>) {
const update = useCallback(
(newValue: string) => {
table.options.meta?.handleUpdate(row.index, column.id, newValue, false);
@@ -138,12 +138,12 @@ function MakeSingleLineField({ row, column, table }: CellContext<OntimeRundownEn
return null;
}
const initialValue = event[column.id as keyof OntimeRundownEntry] ?? '';
const initialValue = event[column.id as keyof OntimeEntry] ?? '';
return <SingleLineCell initialValue={initialValue} handleUpdate={update} />;
return <SingleLineCell initialValue={initialValue as string} handleUpdate={update} />;
}
function MakeCustomField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
function MakeCustomField({ row, column, table }: CellContext<OntimeEntry, unknown>) {
const update = useCallback(
(newValue: string) => {
table.options.meta?.handleUpdate(row.index, column.id, newValue, true);
@@ -161,7 +161,7 @@ function MakeCustomField({ row, column, table }: CellContext<OntimeRundownEntry,
return <MultiLineCell initialValue={initialValue} handleUpdate={update} />;
}
export function makeCuesheetColumns(customFields: CustomFields): ColumnDef<OntimeRundownEntry>[] {
export function makeCuesheetColumns(customFields: CustomFields): ColumnDef<OntimeEntry>[] {
const dynamicCustomFields = Object.keys(customFields).map((key) => ({
accessorKey: key,
id: key,
@@ -1,7 +1,7 @@
import { memo, ReactNode } from 'react';
import { Button, Checkbox } from '@chakra-ui/react';
import { Column } from '@tanstack/react-table';
import { OntimeRundownEntry } from 'ontime-types';
import { OntimeEntry } from 'ontime-types';
import * as Editor from '../../../../features/editors/editor-utils/EditorUtils';
@@ -14,7 +14,7 @@ const buttonProps = {
};
interface CuesheetTableSettingsProps {
columns: Column<OntimeRundownEntry, unknown>[];
columns: Column<OntimeEntry, unknown>[];
handleResetResizing: () => void;
handleResetReordering: () => void;
handleClearToggles: () => void;
@@ -1,9 +1,9 @@
import { useCallback, useEffect } from 'react';
import { useLocalStorage } from '@mantine/hooks';
import { ColumnDef } from '@tanstack/react-table';
import { OntimeRundownEntry } from 'ontime-types';
import { OntimeEntry } from 'ontime-types';
export default function useColumnManager(columns: ColumnDef<OntimeRundownEntry>[]) {
export default function useColumnManager(columns: ColumnDef<OntimeEntry>[]) {
const [columnVisibility, setColumnVisibility] = useLocalStorage({ key: 'table-hidden', defaultValue: {} });
const [columnOrder, saveColumnOrder] = useLocalStorage<string[]>({
key: 'table-order',
@@ -3,8 +3,8 @@ import {
isOntimeDelay,
isOntimeEvent,
MaybeNumber,
OntimeEntry,
OntimeEntryCommonKeys,
OntimeRundown,
ProjectData,
} from 'ontime-types';
import { millisToString } from 'ontime-utils';
@@ -32,12 +32,8 @@ export const parseField = (field: CsvHeaderKey, data: unknown): string => {
/**
* @description Creates an array of arrays usable by xlsx for export
* @param {ProjectData} headerData
* @param {OntimeRundown} rundown
* @param {CustomFields} customFields
* @return {(string[])[]}
*/
export const makeTable = (headerData: ProjectData, rundown: OntimeRundown, customFields: CustomFields): string[][] => {
export const makeTable = (headerData: ProjectData, rundown: OntimeEntry[], customFields: CustomFields): string[][] => {
// create metadata header row
const data = [['Ontime · Rundown export']];
if (headerData.title) data.push([`Project title: ${headerData.title}`]);
+2 -2
View File
@@ -1,6 +1,6 @@
import { memo } from 'react';
import { useViewportSize } from '@mantine/hooks';
import { isOntimeEvent, isPlayableEvent, OntimeRundown } from 'ontime-types';
import { isOntimeEvent, isPlayableEvent, OntimeEntry } from 'ontime-types';
import { dayInMs, getLastEvent, MILLIS_PER_HOUR } from 'ontime-utils';
import TimelineMarkers from './timeline-markers/TimelineMarkers';
@@ -11,7 +11,7 @@ import style from './Timeline.module.scss';
interface TimelineProps {
firstStart: number;
rundown: OntimeRundown;
rundown: OntimeEntry[];
selectedEventId: string | null;
totalDuration: number;
}
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { isOntimeEvent, isPlayableEvent, MaybeString, OntimeEvent, OntimeRundown, PlayableEvent } from 'ontime-types';
import { isOntimeEvent, isPlayableEvent, MaybeString, OntimeEntry, OntimeEvent, PlayableEvent } from 'ontime-types';
import {
dayInMs,
getEventWithId,
@@ -87,7 +87,7 @@ interface ScopedRundownData {
totalDuration: number;
}
export function useScopedRundown(rundown: OntimeRundown, selectedEventId: MaybeString): ScopedRundownData {
export function useScopedRundown(rundown: OntimeEntry[], selectedEventId: MaybeString): ScopedRundownData {
const [searchParams] = useSearchParams();
const data = useMemo(() => {
@@ -102,7 +102,7 @@ export function useScopedRundown(rundown: OntimeRundown, selectedEventId: MaybeS
let selectedIndex = selectedEventId ? Infinity : -1;
let firstStart = null;
let totalDuration = 0;
let lastEntry: PlayableEvent | undefined;
let lastEntry: PlayableEvent | null = null;
for (let i = 0; i < rundown.length; i++) {
const currentEntry = rundown[i];
@@ -164,7 +164,7 @@ type UpcomingEvents = {
/**
* Returns upcoming events from current: now, next and followedBy
*/
export function getUpcomingEvents(events: OntimeRundown, selectedId: MaybeString): UpcomingEvents {
export function getUpcomingEvents(events: PlayableEvent[], selectedId: MaybeString): UpcomingEvents {
if (events.length === 0) {
return { now: null, next: null, followedBy: null };
}