diff --git a/apps/client/src/features/operator/Operator.tsx b/apps/client/src/features/operator/Operator.tsx index ef8331f60..f46ac1f3a 100644 --- a/apps/client/src/features/operator/Operator.tsx +++ b/apps/client/src/features/operator/Operator.tsx @@ -6,13 +6,10 @@ import ViewParamsEditor from '../../common/components/view-params-editor/ViewPar import useFollowComponent from '../../common/hooks/useFollowComponent'; import { useSelectedEventId } from '../../common/hooks/useSocket'; import { useWindowTitle } from '../../common/hooks/useWindowTitle'; -import useCustomFields from '../../common/hooks-query/useCustomFields'; -import useProjectData from '../../common/hooks-query/useProjectData'; -import { useRundownWithMetadata } from '../../common/hooks-query/useRundown'; -import useSettings from '../../common/hooks-query/useSettings'; import { cx } from '../../common/utils/styleUtils'; import { throttle } from '../../common/utils/throttle'; import { getDefaultFormat } from '../../common/utils/time'; +import Loader from '../../views/common/loader/Loader'; import EditModal from './edit-modal/EditModal'; import FollowButton from './follow-button/FollowButton'; @@ -22,21 +19,31 @@ import StatusBar from './status-bar/StatusBar'; import { getOperatorOptions, useOperatorOptions } from './operator.options'; import type { EditEvent } from './operator.types'; import { getEventData } from './operator.utils'; +import { OperatorData, useOperatorData } from './useOperatorData'; import style from './Operator.module.scss'; const selectedOffset = 50; -export default function Operator() { - const { data, rundownMetadata, status } = useRundownWithMetadata(); - const { data: customFields, status: customFieldStatus } = useCustomFields(); - const { data: projectData, status: projectDataStatus } = useProjectData(); +export default function OperatorLoader() { + const { data, status } = useOperatorData(); - const timeoutId = useRef(null); + useWindowTitle('Operator'); + if (status === 'pending') { + return ; + } + + if (status === 'error') { + return ; + } + + return ; +} + +function Operator({ rundown, rundownMetadata, customFields, settings }: OperatorData) { const { selectedEventId } = useSelectedEventId(); const { subscribe, mainSource, secondarySource, shouldEdit, hidePast, showStart } = useOperatorOptions(); - const { data: settings } = useSettings(); const [showEditPrompt, setShowEditPrompt] = useState(false); const [editEvent, setEditEvent] = useState(null); @@ -52,7 +59,7 @@ export default function Operator() { followTrigger: selectedEventId, }); - useWindowTitle('Operator'); + const timeoutId = useRef(null); // reset scroll if nothing is selected useEffect(() => { @@ -101,17 +108,10 @@ export default function Operator() { setEditEvent({ ...event }); }, []); - const missingData = !data || !customFields || !projectData; - const isLoading = status === 'pending' || customFieldStatus === 'pending' || projectDataStatus === 'pending'; - // gather option data const defaultFormat = getDefaultFormat(settings?.timeFormat); const operatorOptions = useMemo(() => getOperatorOptions(customFields, defaultFormat), [customFields, defaultFormat]); - if (missingData || isLoading) { - return ; - } - const canEdit = shouldEdit && subscribe.length; return ( @@ -126,8 +126,8 @@ export default function Operator() { )}
- {data.order.map((entryId) => { - const entry = data.entries[entryId]; + {rundown.order.map((entryId) => { + const entry = rundown.entries[entryId]; if (isOntimeEvent(entry)) { const { isPast, isLinkedToLoaded, isLoaded, totalGap } = rundownMetadata[entryId]; // hide past events (if setting) and skipped events @@ -172,7 +172,7 @@ export default function Operator() { {entry.entries.map((nestedEntryId) => { - const nestedEntry = data.entries[nestedEntryId]; + const nestedEntry = rundown.entries[nestedEntryId]; if (!isOntimeEvent(nestedEntry)) { return null; } diff --git a/apps/client/src/features/operator/useOperatorData.ts b/apps/client/src/features/operator/useOperatorData.ts new file mode 100644 index 000000000..0164d4be3 --- /dev/null +++ b/apps/client/src/features/operator/useOperatorData.ts @@ -0,0 +1,30 @@ +import { CustomFields, Rundown, Settings } from 'ontime-types'; + +import useCustomFields from '../../common/hooks-query/useCustomFields'; +import { useRundownWithMetadata } from '../../common/hooks-query/useRundown'; +import useSettings from '../../common/hooks-query/useSettings'; +import { RundownMetadataObject } from '../../common/utils/rundownMetadata'; +import { aggregateQueryStatus, ViewData } from '../../views/utils/viewLoader.utils'; + +export interface OperatorData { + rundown: Rundown; + rundownMetadata: RundownMetadataObject; + customFields: CustomFields; + settings: Settings; +} + +export function useOperatorData(): ViewData { + const { data: rundown, rundownMetadata, status: rundownStatus } = useRundownWithMetadata(); + const { data: customFields, status: customFieldStatus } = useCustomFields(); + const { data: settings, status: settingsStatus } = useSettings(); + + return { + data: { + rundown, + rundownMetadata, + customFields, + settings, + }, + status: aggregateQueryStatus([rundownStatus, customFieldStatus, settingsStatus]), + }; +}