mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-15 04:13:47 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f2455fec17 | |||
| f7b58f5ebd | |||
| 9e2dfaab16 | |||
| 65e1d3cfe9 |
@@ -8,12 +8,12 @@ import { getCustomFields } from '../api/customFields';
|
|||||||
const placeholder: CustomFields = {};
|
const placeholder: CustomFields = {};
|
||||||
|
|
||||||
export default function useCustomFields() {
|
export default function useCustomFields() {
|
||||||
const { data, status, isFetching, isError, refetch } = useQuery({
|
const { data, status, isFetching, isError, isLoadingError, refetch } = useQuery({
|
||||||
queryKey: CUSTOM_FIELDS,
|
queryKey: CUSTOM_FIELDS,
|
||||||
queryFn: ({ signal }) => getCustomFields({ signal }),
|
queryFn: ({ signal }) => getCustomFields({ signal }),
|
||||||
placeholderData: (previousData, _previousQuery) => previousData,
|
placeholderData: (previousData, _previousQuery) => previousData,
|
||||||
refetchInterval: queryRefetchIntervalSlow,
|
refetchInterval: queryRefetchIntervalSlow,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { data: data ?? placeholder, status, isFetching, isError, refetch };
|
return { data: data ?? placeholder, status, isFetching, isError, isLoadingError, refetch };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import { getProjectData, postProjectData } from '../api/project';
|
|||||||
import { projectDataPlaceholder } from '../models/ProjectData';
|
import { projectDataPlaceholder } from '../models/ProjectData';
|
||||||
|
|
||||||
export default function useProjectData() {
|
export default function useProjectData() {
|
||||||
const { data, status, isFetching, isError, refetch } = useQuery({
|
const { data, status, isFetching, isError, isLoadingError, refetch } = useQuery({
|
||||||
queryKey: PROJECT_DATA,
|
queryKey: PROJECT_DATA,
|
||||||
queryFn: ({ signal }) => getProjectData({ signal }),
|
queryFn: ({ signal }) => getProjectData({ signal }),
|
||||||
placeholderData: (previousData, _previousQuery) => previousData,
|
placeholderData: (previousData, _previousQuery) => previousData,
|
||||||
refetchInterval: queryRefetchIntervalSlow,
|
refetchInterval: queryRefetchIntervalSlow,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { data: data ?? projectDataPlaceholder, status, isFetching, isError, refetch };
|
return { data: data ?? projectDataPlaceholder, status, isFetching, isError, isLoadingError, refetch };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useUpdateProjectData() {
|
export function useUpdateProjectData() {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export default function useRundown() {
|
|||||||
data: { loaded: loadedRundownId },
|
data: { loaded: loadedRundownId },
|
||||||
} = useProjectRundowns();
|
} = useProjectRundowns();
|
||||||
|
|
||||||
const { data, status, isError, refetch, isFetching } = useQuery<Rundown>({
|
const { data, status, isError, isLoadingError, refetch, isFetching } = useQuery<Rundown>({
|
||||||
queryKey: loadedRundownId ? getRundownQueryKey(loadedRundownId) : CURRENT_RUNDOWN_QUERY_KEY,
|
queryKey: loadedRundownId ? getRundownQueryKey(loadedRundownId) : CURRENT_RUNDOWN_QUERY_KEY,
|
||||||
queryFn: ({ signal }) => fetchCurrentRundown({ signal }),
|
queryFn: ({ signal }) => fetchCurrentRundown({ signal }),
|
||||||
refetchInterval: queryRefetchIntervalSlow,
|
refetchInterval: queryRefetchIntervalSlow,
|
||||||
@@ -50,14 +50,14 @@ export default function useRundown() {
|
|||||||
queryClient.removeQueries({ queryKey: CURRENT_RUNDOWN_QUERY_KEY, exact: true });
|
queryClient.removeQueries({ queryKey: CURRENT_RUNDOWN_QUERY_KEY, exact: true });
|
||||||
}, [loadedRundownId, queryClient]);
|
}, [loadedRundownId, queryClient]);
|
||||||
|
|
||||||
return { data: data ?? cachedRundownPlaceholder, status, isError, refetch, isFetching };
|
return { data: data ?? cachedRundownPlaceholder, status, isError, isLoadingError, refetch, isFetching };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useRundownWithMetadata() {
|
export function useRundownWithMetadata() {
|
||||||
const { data, status } = useRundown();
|
const { data, status, isLoadingError } = useRundown();
|
||||||
const selectedEventId = useSelectedEventId();
|
const selectedEventId = useSelectedEventId();
|
||||||
const rundownMetadata = useMemo(() => getRundownMetadata(data, selectedEventId), [data, selectedEventId]);
|
const rundownMetadata = useMemo(() => getRundownMetadata(data, selectedEventId), [data, selectedEventId]);
|
||||||
return { data, status, rundownMetadata };
|
return { data, status, isLoadingError, rundownMetadata };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,7 +65,7 @@ export function useRundownWithMetadata() {
|
|||||||
* built from the order and rundown fields
|
* built from the order and rundown fields
|
||||||
*/
|
*/
|
||||||
export function useFlatRundown() {
|
export function useFlatRundown() {
|
||||||
const { data, status } = useRundown();
|
const { data, status, isLoadingError } = useRundown();
|
||||||
|
|
||||||
const flatRundown = useMemo(() => {
|
const flatRundown = useMemo(() => {
|
||||||
if (data.revision === -1) {
|
if (data.revision === -1) {
|
||||||
@@ -74,15 +74,15 @@ export function useFlatRundown() {
|
|||||||
return data.flatOrder.map((id) => data.entries[id]).filter((entry): entry is OntimeEntry => entry !== undefined);
|
return data.flatOrder.map((id) => data.entries[id]).filter((entry): entry is OntimeEntry => entry !== undefined);
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
return { data: flatRundown, rundownId: data.id, status };
|
return { data: flatRundown, rundownId: data.id, status, isLoadingError };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useFlatRundownWithMetadata() {
|
export function useFlatRundownWithMetadata() {
|
||||||
const { data, status } = useRundown();
|
const { data, status, isLoadingError } = useRundown();
|
||||||
const selectedEventId = useSelectedEventId();
|
const selectedEventId = useSelectedEventId();
|
||||||
|
|
||||||
const rundownWithMetadata = useMemo(() => getFlatRundownMetadata(data, selectedEventId), [data, selectedEventId]);
|
const rundownWithMetadata = useMemo(() => getFlatRundownMetadata(data, selectedEventId), [data, selectedEventId]);
|
||||||
return { data: rundownWithMetadata, status };
|
return { data: rundownWithMetadata, status, isLoadingError };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +127,7 @@ export function useRundownAuxData() {
|
|||||||
export function useRundownById(rundownId: string | null | undefined) {
|
export function useRundownById(rundownId: string | null | undefined) {
|
||||||
const enabled = Boolean(rundownId);
|
const enabled = Boolean(rundownId);
|
||||||
|
|
||||||
const { data, status, isError, refetch, isFetching } = useQuery<Rundown>({
|
const { data, status, isError, isLoadingError, refetch, isFetching } = useQuery<Rundown>({
|
||||||
queryKey: getRundownQueryKey(rundownId ?? ''),
|
queryKey: getRundownQueryKey(rundownId ?? ''),
|
||||||
queryFn: ({ signal }) => fetchRundown(rundownId!, { signal }),
|
queryFn: ({ signal }) => fetchRundown(rundownId!, { signal }),
|
||||||
enabled,
|
enabled,
|
||||||
@@ -135,5 +135,5 @@ export function useRundownById(rundownId: string | null | undefined) {
|
|||||||
refetchInterval: queryRefetchIntervalSlow,
|
refetchInterval: queryRefetchIntervalSlow,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { data: data ?? cachedRundownPlaceholder, status, isError, refetch, isFetching };
|
return { data: data ?? cachedRundownPlaceholder, status, isError, isLoadingError, refetch, isFetching };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export type RundownSource = {
|
|||||||
rundown: Rundown;
|
rundown: Rundown;
|
||||||
flatRundown: ExtendedEntry[];
|
flatRundown: ExtendedEntry[];
|
||||||
status: string;
|
status: string;
|
||||||
|
isLoadingError: boolean;
|
||||||
selectedEventId: EntryId | null;
|
selectedEventId: EntryId | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ function useRundownSource(rundownId: string | null, loadedRundownId: string | nu
|
|||||||
const isLoadedTarget = rundownId !== null && rundownId === loadedRundownId;
|
const isLoadedTarget = rundownId !== null && rundownId === loadedRundownId;
|
||||||
const runtimeSelectedEventId = useSelectedEventId();
|
const runtimeSelectedEventId = useSelectedEventId();
|
||||||
const effectiveSelectedEventId = isLoadedTarget ? runtimeSelectedEventId : null;
|
const effectiveSelectedEventId = isLoadedTarget ? runtimeSelectedEventId : null;
|
||||||
const { data: rundown, status } = useRundownById(rundownId);
|
const { data: rundown, status, isLoadingError } = useRundownById(rundownId);
|
||||||
const flatRundown = useMemo(
|
const flatRundown = useMemo(
|
||||||
() => getFlatRundownMetadata(rundown, effectiveSelectedEventId),
|
() => getFlatRundownMetadata(rundown, effectiveSelectedEventId),
|
||||||
[effectiveSelectedEventId, rundown],
|
[effectiveSelectedEventId, rundown],
|
||||||
@@ -47,8 +48,9 @@ function useRundownSource(rundownId: string | null, loadedRundownId: string | nu
|
|||||||
rundown,
|
rundown,
|
||||||
flatRundown,
|
flatRundown,
|
||||||
status,
|
status,
|
||||||
|
isLoadingError,
|
||||||
selectedEventId: effectiveSelectedEventId,
|
selectedEventId: effectiveSelectedEventId,
|
||||||
}),
|
}),
|
||||||
[effectiveSelectedEventId, flatRundown, rundown, rundownId, status],
|
[effectiveSelectedEventId, flatRundown, isLoadingError, rundown, rundownId, status],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { getSettings } from '../api/settings';
|
|||||||
import { ontimePlaceholderSettings } from '../models/OntimeSettings';
|
import { ontimePlaceholderSettings } from '../models/OntimeSettings';
|
||||||
|
|
||||||
export default function useSettings() {
|
export default function useSettings() {
|
||||||
const { data, status, isFetching, isError, refetch } = useQuery({
|
const { data, status, isFetching, isError, isLoadingError, refetch } = useQuery({
|
||||||
queryKey: APP_SETTINGS,
|
queryKey: APP_SETTINGS,
|
||||||
queryFn: ({ signal }) => getSettings({ signal }),
|
queryFn: ({ signal }) => getSettings({ signal }),
|
||||||
placeholderData: (previousData, _previousQuery) => previousData,
|
placeholderData: (previousData, _previousQuery) => previousData,
|
||||||
@@ -22,5 +22,5 @@ export default function useSettings() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return { data: data ?? ontimePlaceholderSettings, status, isFetching, isError, refetch };
|
return { data: data ?? ontimePlaceholderSettings, status, isFetching, isError, isLoadingError, refetch };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { VIEW_SETTINGS } from '../api/constants';
|
|||||||
import { viewsSettingsPlaceholder } from '../models/ViewSettings.type';
|
import { viewsSettingsPlaceholder } from '../models/ViewSettings.type';
|
||||||
|
|
||||||
export default function useViewSettings() {
|
export default function useViewSettings() {
|
||||||
const { data, status } = useQuery({
|
const { data, status, isLoadingError } = useQuery({
|
||||||
queryKey: VIEW_SETTINGS,
|
queryKey: VIEW_SETTINGS,
|
||||||
queryFn: ({ signal }) => getViewSettings({ signal }),
|
queryFn: ({ signal }) => getViewSettings({ signal }),
|
||||||
placeholderData: (previousData, _previousQuery) => previousData,
|
placeholderData: (previousData, _previousQuery) => previousData,
|
||||||
@@ -24,5 +24,5 @@ export default function useViewSettings() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return { data: data ?? viewsSettingsPlaceholder, status, mutateAsync };
|
return { data: data ?? viewsSettingsPlaceholder, status, isLoadingError, mutateAsync };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,18 @@ export interface OperatorData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useOperatorData(): ViewData<OperatorData> {
|
export function useOperatorData(): ViewData<OperatorData> {
|
||||||
const { data: rundown, rundownMetadata, status: rundownStatus } = useRundownWithMetadata();
|
const {
|
||||||
const { data: customFields, status: customFieldStatus } = useCustomFields();
|
data: rundown,
|
||||||
const { data: settings, status: settingsStatus } = useSettings();
|
rundownMetadata,
|
||||||
|
status: rundownStatus,
|
||||||
|
isLoadingError: rundownIsLoadingError,
|
||||||
|
} = useRundownWithMetadata();
|
||||||
|
const {
|
||||||
|
data: customFields,
|
||||||
|
status: customFieldStatus,
|
||||||
|
isLoadingError: customFieldIsLoadingError,
|
||||||
|
} = useCustomFields();
|
||||||
|
const { data: settings, status: settingsStatus, isLoadingError: settingsIsLoadingError } = useSettings();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
@@ -25,6 +34,10 @@ export function useOperatorData(): ViewData<OperatorData> {
|
|||||||
customFields,
|
customFields,
|
||||||
settings,
|
settings,
|
||||||
},
|
},
|
||||||
status: aggregateQueryStatus([rundownStatus, customFieldStatus, settingsStatus]),
|
status: aggregateQueryStatus([
|
||||||
|
{ status: rundownStatus, isLoadingError: rundownIsLoadingError },
|
||||||
|
{ status: customFieldStatus, isLoadingError: customFieldIsLoadingError },
|
||||||
|
{ status: settingsStatus, isLoadingError: settingsIsLoadingError },
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import Rundown from './Rundown';
|
|||||||
|
|
||||||
export default memo(RundownList);
|
export default memo(RundownList);
|
||||||
function RundownList() {
|
function RundownList() {
|
||||||
const { data, status, rundownMetadata } = useRundownWithMetadata();
|
const { data, status, isLoadingError, rundownMetadata } = useRundownWithMetadata();
|
||||||
const featureData = useRundownEditor();
|
const featureData = useRundownEditor();
|
||||||
const { getLocalizedString } = useTranslation();
|
const { getLocalizedString } = useTranslation();
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ function RundownList() {
|
|||||||
return <EmptyFill text='Loading…' />;
|
return <EmptyFill text='Loading…' />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === 'error') {
|
if (isLoadingError) {
|
||||||
return <EmptyFill text={getLocalizedString('common.no_data')} />;
|
return <EmptyFill text={getLocalizedString('common.no_data')} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,14 @@ export function useBackstageData(): ViewData<BackstageData> {
|
|||||||
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
||||||
|
|
||||||
// HTTP API data
|
// HTTP API data
|
||||||
const { data: rundownData, status: rundownStatus } = useFlatRundown();
|
const { data: rundownData, status: rundownStatus, isLoadingError: rundownIsLoadingError } = useFlatRundown();
|
||||||
const { data: projectData, status: projectDataStatus } = useProjectData();
|
const { data: projectData, status: projectDataStatus, isLoadingError: projectDataIsLoadingError } = useProjectData();
|
||||||
const { data: settings, status: settingsStatus } = useSettings();
|
const { data: settings, status: settingsStatus, isLoadingError: settingsIsLoadingError } = useSettings();
|
||||||
const { data: customFields, status: customFieldsStatus } = useCustomFields();
|
const {
|
||||||
|
data: customFields,
|
||||||
|
status: customFieldsStatus,
|
||||||
|
isLoadingError: customFieldsIsLoadingError,
|
||||||
|
} = useCustomFields();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
@@ -33,6 +37,11 @@ export function useBackstageData(): ViewData<BackstageData> {
|
|||||||
isMirrored,
|
isMirrored,
|
||||||
settings,
|
settings,
|
||||||
},
|
},
|
||||||
status: aggregateQueryStatus([rundownStatus, projectDataStatus, settingsStatus, customFieldsStatus]),
|
status: aggregateQueryStatus([
|
||||||
|
{ status: rundownStatus, isLoadingError: rundownIsLoadingError },
|
||||||
|
{ status: projectDataStatus, isLoadingError: projectDataIsLoadingError },
|
||||||
|
{ status: settingsStatus, isLoadingError: settingsIsLoadingError },
|
||||||
|
{ status: customFieldsStatus, isLoadingError: customFieldsIsLoadingError },
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,18 @@ export function useCountdownData(): ViewData<CountdownData> {
|
|||||||
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
||||||
|
|
||||||
// HTTP API data
|
// HTTP API data
|
||||||
const { data: rundownData, status: rundownStatus } = useFlatRundownWithMetadata();
|
const {
|
||||||
const { data: projectData, status: projectDataStatus } = useProjectData();
|
data: rundownData,
|
||||||
const { data: settings, status: settingsStatus } = useSettings();
|
status: rundownStatus,
|
||||||
const { data: customFields, status: customFieldsStatus } = useCustomFields();
|
isLoadingError: rundownIsLoadingError,
|
||||||
|
} = useFlatRundownWithMetadata();
|
||||||
|
const { data: projectData, status: projectDataStatus, isLoadingError: projectDataIsLoadingError } = useProjectData();
|
||||||
|
const { data: settings, status: settingsStatus, isLoadingError: settingsIsLoadingError } = useSettings();
|
||||||
|
const {
|
||||||
|
data: customFields,
|
||||||
|
status: customFieldsStatus,
|
||||||
|
isLoadingError: customFieldsIsLoadingError,
|
||||||
|
} = useCustomFields();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
@@ -34,6 +42,11 @@ export function useCountdownData(): ViewData<CountdownData> {
|
|||||||
isMirrored,
|
isMirrored,
|
||||||
settings,
|
settings,
|
||||||
},
|
},
|
||||||
status: aggregateQueryStatus([rundownStatus, projectDataStatus, settingsStatus, customFieldsStatus]),
|
status: aggregateQueryStatus([
|
||||||
|
{ status: rundownStatus, isLoadingError: rundownIsLoadingError },
|
||||||
|
{ status: projectDataStatus, isLoadingError: projectDataIsLoadingError },
|
||||||
|
{ status: settingsStatus, isLoadingError: settingsIsLoadingError },
|
||||||
|
{ status: customFieldsStatus, isLoadingError: customFieldsIsLoadingError },
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default function CuesheetTable({
|
|||||||
isCurrentRundown,
|
isCurrentRundown,
|
||||||
insertElement,
|
insertElement,
|
||||||
}: CuesheetTableProps) {
|
}: CuesheetTableProps) {
|
||||||
const { flatRundown, status, selectedEventId } = source;
|
const { flatRundown, status, isLoadingError, selectedEventId } = source;
|
||||||
const { updateEntry, updateTimer, addEntry } = useEntryActionsContext();
|
const { updateEntry, updateTimer, addEntry } = useEntryActionsContext();
|
||||||
const { getLocalizedString } = useTranslation();
|
const { getLocalizedString } = useTranslation();
|
||||||
const canCreateEntries = useCuesheetPermissions((state) => state.canCreateEntries) && cuesheetMode === AppMode.Edit;
|
const canCreateEntries = useCuesheetPermissions((state) => state.canCreateEntries) && cuesheetMode === AppMode.Edit;
|
||||||
@@ -235,7 +235,7 @@ export default function CuesheetTable({
|
|||||||
return <EmptyFill text='Loading…' className={style.tableLoading} />;
|
return <EmptyFill text='Loading…' className={style.tableLoading} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === 'error') {
|
if (isLoadingError) {
|
||||||
return <EmptyFill text={getLocalizedString('common.no_data')} className={style.tableLoading} />;
|
return <EmptyFill text={getLocalizedString('common.no_data')} className={style.tableLoading} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ProjectData } from 'ontime-types';
|
|||||||
|
|
||||||
import useProjectData from '../../common/hooks-query/useProjectData';
|
import useProjectData from '../../common/hooks-query/useProjectData';
|
||||||
import { useViewOptionsStore } from '../../common/stores/viewOptions';
|
import { useViewOptionsStore } from '../../common/stores/viewOptions';
|
||||||
import { ViewData } from '../utils/viewLoader.utils';
|
import { ViewData, aggregateQueryStatus } from '../utils/viewLoader.utils';
|
||||||
|
|
||||||
export interface ProjectInfoData {
|
export interface ProjectInfoData {
|
||||||
projectData: ProjectData;
|
projectData: ProjectData;
|
||||||
@@ -14,13 +14,13 @@ export function useProjectInfoData(): ViewData<ProjectInfoData> {
|
|||||||
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
||||||
|
|
||||||
// HTTP API data
|
// HTTP API data
|
||||||
const { data: projectData, status: projectDataStatus } = useProjectData();
|
const { data: projectData, status: projectDataStatus, isLoadingError: projectDataIsLoadingError } = useProjectData();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
projectData,
|
projectData,
|
||||||
isMirrored,
|
isMirrored,
|
||||||
},
|
},
|
||||||
status: projectDataStatus,
|
status: aggregateQueryStatus([{ status: projectDataStatus, isLoadingError: projectDataIsLoadingError }]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,18 @@ export function useStudioData(): ViewData<StudioData> {
|
|||||||
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
||||||
|
|
||||||
// HTTP API data
|
// HTTP API data
|
||||||
const { data: projectData, status: projectDataStatus } = useProjectData();
|
const { data: projectData, status: projectDataStatus, isLoadingError: projectDataIsLoadingError } = useProjectData();
|
||||||
const { data: viewSettings, status: viewSettingsStatus } = useViewSettings();
|
const {
|
||||||
const { data: settings, status: settingsStatus } = useSettings();
|
data: viewSettings,
|
||||||
const { data: customFields, status: customFieldsStatus } = useCustomFields();
|
status: viewSettingsStatus,
|
||||||
|
isLoadingError: viewSettingsIsLoadingError,
|
||||||
|
} = useViewSettings();
|
||||||
|
const { data: settings, status: settingsStatus, isLoadingError: settingsIsLoadingError } = useSettings();
|
||||||
|
const {
|
||||||
|
data: customFields,
|
||||||
|
status: customFieldsStatus,
|
||||||
|
isLoadingError: customFieldsIsLoadingError,
|
||||||
|
} = useCustomFields();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
@@ -33,6 +41,11 @@ export function useStudioData(): ViewData<StudioData> {
|
|||||||
settings,
|
settings,
|
||||||
viewSettings,
|
viewSettings,
|
||||||
},
|
},
|
||||||
status: aggregateQueryStatus([projectDataStatus, viewSettingsStatus, settingsStatus, customFieldsStatus]),
|
status: aggregateQueryStatus([
|
||||||
|
{ status: projectDataStatus, isLoadingError: projectDataIsLoadingError },
|
||||||
|
{ status: viewSettingsStatus, isLoadingError: viewSettingsIsLoadingError },
|
||||||
|
{ status: settingsStatus, isLoadingError: settingsIsLoadingError },
|
||||||
|
{ status: customFieldsStatus, isLoadingError: customFieldsIsLoadingError },
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,18 @@ export interface TimelineData {
|
|||||||
|
|
||||||
export function useTimelineData(): ViewData<TimelineData> {
|
export function useTimelineData(): ViewData<TimelineData> {
|
||||||
// HTTP API data
|
// HTTP API data
|
||||||
const { data: rundownData, status: rundownStatus } = useFlatRundownWithMetadata();
|
const {
|
||||||
const { data: projectData, status: projectDataStatus } = useProjectData();
|
data: rundownData,
|
||||||
const { data: settings, status: settingsStatus } = useSettings();
|
status: rundownStatus,
|
||||||
const { data: customFields, status: customFieldsStatus } = useCustomFields();
|
isLoadingError: rundownIsLoadingError,
|
||||||
|
} = useFlatRundownWithMetadata();
|
||||||
|
const { data: projectData, status: projectDataStatus, isLoadingError: projectDataIsLoadingError } = useProjectData();
|
||||||
|
const { data: settings, status: settingsStatus, isLoadingError: settingsIsLoadingError } = useSettings();
|
||||||
|
const {
|
||||||
|
data: customFields,
|
||||||
|
status: customFieldsStatus,
|
||||||
|
isLoadingError: customFieldsIsLoadingError,
|
||||||
|
} = useCustomFields();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
@@ -28,6 +36,11 @@ export function useTimelineData(): ViewData<TimelineData> {
|
|||||||
projectData,
|
projectData,
|
||||||
settings,
|
settings,
|
||||||
},
|
},
|
||||||
status: aggregateQueryStatus([rundownStatus, projectDataStatus, settingsStatus, customFieldsStatus]),
|
status: aggregateQueryStatus([
|
||||||
|
{ status: rundownStatus, isLoadingError: rundownIsLoadingError },
|
||||||
|
{ status: projectDataStatus, isLoadingError: projectDataIsLoadingError },
|
||||||
|
{ status: settingsStatus, isLoadingError: settingsIsLoadingError },
|
||||||
|
{ status: customFieldsStatus, isLoadingError: customFieldsIsLoadingError },
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,19 @@ export function useTimerData(): ViewData<TimerData> {
|
|||||||
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
const isMirrored = useViewOptionsStore((state) => state.mirror);
|
||||||
|
|
||||||
// HTTP API data
|
// HTTP API data
|
||||||
const { data: projectData, status: projectDataStatus } = useProjectData();
|
const { data: projectData, status: projectDataStatus, isLoadingError: projectDataIsLoadingError } = useProjectData();
|
||||||
const { data: viewSettings, status: viewSettingsStatus } = useViewSettings();
|
const {
|
||||||
const { data: settings, status: settingsStatus } = useSettings();
|
data: viewSettings,
|
||||||
const { data: customFields, status: customFieldsStatus } = useCustomFields();
|
status: viewSettingsStatus,
|
||||||
const { data: rundown, status: rundownStatus } = useRundown();
|
isLoadingError: viewSettingsIsLoadingError,
|
||||||
|
} = useViewSettings();
|
||||||
|
const { data: settings, status: settingsStatus, isLoadingError: settingsIsLoadingError } = useSettings();
|
||||||
|
const {
|
||||||
|
data: customFields,
|
||||||
|
status: customFieldsStatus,
|
||||||
|
isLoadingError: customFieldsIsLoadingError,
|
||||||
|
} = useCustomFields();
|
||||||
|
const { data: rundown, status: rundownStatus, isLoadingError: rundownIsLoadingError } = useRundown();
|
||||||
const { entries } = rundown;
|
const { entries } = rundown;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -39,11 +47,11 @@ export function useTimerData(): ViewData<TimerData> {
|
|||||||
entries,
|
entries,
|
||||||
},
|
},
|
||||||
status: aggregateQueryStatus([
|
status: aggregateQueryStatus([
|
||||||
projectDataStatus,
|
{ status: projectDataStatus, isLoadingError: projectDataIsLoadingError },
|
||||||
viewSettingsStatus,
|
{ status: viewSettingsStatus, isLoadingError: viewSettingsIsLoadingError },
|
||||||
settingsStatus,
|
{ status: settingsStatus, isLoadingError: settingsIsLoadingError },
|
||||||
customFieldsStatus,
|
{ status: customFieldsStatus, isLoadingError: customFieldsIsLoadingError },
|
||||||
rundownStatus,
|
{ status: rundownStatus, isLoadingError: rundownIsLoadingError },
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,21 +5,27 @@ export type ViewData<T> = {
|
|||||||
status: QueryStatus;
|
status: QueryStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type AggregatableQuery = {
|
||||||
|
status: QueryStatus;
|
||||||
|
/** true only when the query has never received data, ie useQuery's isLoadingError */
|
||||||
|
isLoadingError: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aggregates a loading status from multiple query statuses.
|
* Aggregates a loading status from multiple queries, for the purpose of deciding
|
||||||
* If all statuses are 'pending', returns 'pending'.
|
* whether a view can render.
|
||||||
* If all statuses are 'success', returns 'success'.
|
* - 'pending' while any query hasn't settled yet (no result, first fetch in flight)
|
||||||
* If any status is 'error', returns 'error'.
|
* - 'error' once all queries have settled, if any of them never received data
|
||||||
|
* - 'success' once all queries have settled and every one has data to show,
|
||||||
|
* even if a query's last (background) fetch failed
|
||||||
*/
|
*/
|
||||||
export function aggregateQueryStatus(statuses: QueryStatus[]): QueryStatus {
|
export function aggregateQueryStatus(queries: AggregatableQuery[]): QueryStatus {
|
||||||
if (statuses.every((status) => status === 'pending')) {
|
const allSettled = queries.every((query) => query.status !== 'pending');
|
||||||
|
if (!allSettled) {
|
||||||
return 'pending';
|
return 'pending';
|
||||||
}
|
}
|
||||||
if (statuses.every((status) => status === 'success')) {
|
if (queries.some((query) => query.isLoadingError)) {
|
||||||
return 'success';
|
|
||||||
}
|
|
||||||
if (statuses.some((status) => status === 'error')) {
|
|
||||||
return 'error';
|
return 'error';
|
||||||
}
|
}
|
||||||
return 'pending';
|
return 'success';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user