mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-11 18:33:53 +00:00
ae15f3cdc5
* refactor: align header columns * refactor: improve scrollbar visibility * refactor: center align table elements * refactor: make param elements stateful * fix: issue with collapsed elements not loosing value * fix: prevent search params containing multiple alias references * fix: the issue where a file disappears if it is both migrated and recovered in the same load operation (#1744) * refactor: disable group action for elements in groups * refactor: move context menu items into the event element (#1747) * feat: sheet import new features for v4 (#1730) * import milestone * fixup! import milestone * test: milestone import * add entries to group stop on new group or on group-end type * fixup! add entries to group * cleanup * add event target duration * link start if undefined * add skip import type * extract some to the excel paresing functions * tweaks to presentation * move file --------- Co-authored-by: Carlos Valente <carlosvalente@pm.me> * fix: notify runtimeStore of events bieng groupd * fix: improve authentication and stage detection in demo * chore: ship logo with project * fix: client is referenced by name * fix: prevent reflow in event editor * fix: stale render on selected event due to ref mismatch * Create/Load/Delete multiple rundowns (#1696) * refactor: restore last loaded rundown * refactor: initialise rundown in ProjectService * feat: allow switching rundowns ensure on coordination between the db object and the working object server provide list of rundowns implement switch in the UI implement delete implement new rundown button * fix: render order for floating button * refactor: appropriate names to service * refactor: rundown endpoints * refactor: save last loaded rundown ID * refactor: rundown management UI * refactor: emit refetch all on project load --------- Co-authored-by: Carlos Valente <carlosvalente@pm.me> * feat: recover single event subscription * fixup! feat: sheet import new features for v4 (#1730) * fix: prevent dropping a group inside another * fixup! refactor: move context menu items into the event element (#1747) * fix: prevent stale references to custom fields * fix: propagate updates to all rundowns * refactor: client rundown metadata (#1728) * generate metadata in the hook * move test * ensure there is always a last element * use for-loop * update metadata in useEfect * fully extract metadata generation * use direct assignment * cleanup --------- Co-authored-by: Carlos Valente <carlosvalente@pm.me> * refactor: small imporvement and tests for coerce functions (#1752) * refactor: small imporvement and tests for coerce functions add test `coerceString` add test `coerceBoolean` add test `coerceColour` * remove old todo * fix: consistent quick add behaviour * refactor: create flat rundown with metadata * fix: show add buttons on top * feat: allow editing milestones * refactor: style tweaks to rundown elements refactor: milestones are full width refactor: cuesheet header alignment fix: editor styling in cuesheet * refactor: virtualise table * refactor: improve overscan (#1758) * bump version to 4.0.0-alpha.5 --------- Co-authored-by: Alex Christoffer Rasmussen <ac@omnivox.dk>
111 lines
3.5 KiB
TypeScript
111 lines
3.5 KiB
TypeScript
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { EntryId, OntimeEntry, Rundown } from 'ontime-types';
|
|
|
|
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
|
|
import { RUNDOWN } from '../api/constants';
|
|
import { fetchCurrentRundown } from '../api/rundown';
|
|
import { useSelectedEventId } from '../hooks/useSocket';
|
|
import { getFlatRundownMetadata, getRundownMetadata } from '../utils/rundownMetadata';
|
|
|
|
import useProjectData from './useProjectData';
|
|
|
|
// revision is -1 so that the remote revision is higher
|
|
const cachedRundownPlaceholder: Rundown = {
|
|
id: 'default',
|
|
title: '',
|
|
order: [],
|
|
flatOrder: [],
|
|
entries: {},
|
|
revision: -1,
|
|
};
|
|
|
|
/**
|
|
* Normalised rundown data
|
|
*/
|
|
export default function useRundown() {
|
|
const { data, status, isError, refetch, isFetching } = useQuery<Rundown>({
|
|
queryKey: RUNDOWN,
|
|
queryFn: fetchCurrentRundown,
|
|
placeholderData: (previousData, _previousQuery) => previousData,
|
|
refetchInterval: queryRefetchIntervalSlow,
|
|
});
|
|
return { data: data ?? cachedRundownPlaceholder, status, isError, refetch, isFetching };
|
|
}
|
|
|
|
export function useRundownWithMetadata() {
|
|
const { data, status } = useRundown();
|
|
const { selectedEventId } = useSelectedEventId();
|
|
const rundownMetadata = useMemo(() => getRundownMetadata(data, selectedEventId), [data, selectedEventId]);
|
|
return { data, status, rundownMetadata };
|
|
}
|
|
|
|
/**
|
|
* Provides access to a flat rundown
|
|
* built from the order and rundown fields
|
|
*/
|
|
export function useFlatRundown() {
|
|
const { data, status } = useRundown();
|
|
const { data: projectData } = useProjectData();
|
|
|
|
const loadedProject = useRef<string>('');
|
|
const [prevRevision, setPrevRevision] = useState<number>(-1);
|
|
const [flatRundown, setFlatRundown] = useState<OntimeEntry[]>([]);
|
|
|
|
// update data whenever the revision changes
|
|
useEffect(() => {
|
|
if (data.revision !== -1 && data.revision !== prevRevision) {
|
|
const flatRundown = data.flatOrder.map((id) => data.entries[id]);
|
|
setFlatRundown(flatRundown);
|
|
setPrevRevision(data.revision);
|
|
}
|
|
}, [data.entries, data.flatOrder, data.revision, prevRevision]);
|
|
|
|
// TODO: should we have a project id field?
|
|
// TODO(v4): cleanup as part of load multiple rundowns
|
|
// invalidate current version if project changes
|
|
useEffect(() => {
|
|
if (projectData?.title !== loadedProject.current) {
|
|
setPrevRevision(-1);
|
|
loadedProject.current = projectData?.title ?? '';
|
|
}
|
|
}, [projectData]);
|
|
|
|
return { data: flatRundown, rundownId: data.id, status };
|
|
}
|
|
|
|
export function useFlatRundownWithMetadata() {
|
|
const { data, status } = useRundown();
|
|
const { selectedEventId } = useSelectedEventId();
|
|
|
|
const rundownWithMetadata = useMemo(() => getFlatRundownMetadata(data, selectedEventId), [data, selectedEventId]);
|
|
return { data: rundownWithMetadata, status };
|
|
}
|
|
|
|
/**
|
|
* Provides access to a partial rundown based on a filter callback
|
|
*/
|
|
export function usePartialRundown(cb: (event: OntimeEntry) => boolean) {
|
|
const { data, status } = useFlatRundown();
|
|
const filteredData = useMemo(() => {
|
|
return data.filter(cb);
|
|
}, [data, cb]);
|
|
|
|
return { data: filteredData, status };
|
|
}
|
|
|
|
/**
|
|
* Hook to get a specific entry by ID from the rundown
|
|
*/
|
|
export function useEntry(entryId: EntryId | null): OntimeEntry | null {
|
|
const { data: rundown } = useRundown();
|
|
|
|
// track the specific entry we care about
|
|
const entry = useMemo(() => {
|
|
if (entryId === null) return null;
|
|
return rundown.entries[entryId];
|
|
}, [entryId, rundown.entries]);
|
|
|
|
return entry;
|
|
}
|