mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 15:09:10 +00:00
refactor: allow filtering schedule
This commit is contained in:
committed by
Carlos Valente
parent
8d2db7ffcd
commit
a8fe8b5f1e
@@ -10,13 +10,14 @@ import {
|
|||||||
makeProjectDataOptions,
|
makeProjectDataOptions,
|
||||||
} from '../../common/components/view-params-editor/viewParams.utils';
|
} from '../../common/components/view-params-editor/viewParams.utils';
|
||||||
import { PresetContext } from '../../common/context/PresetContext';
|
import { PresetContext } from '../../common/context/PresetContext';
|
||||||
import { scheduleOptions } from '../common/schedule/schedule.options';
|
import { getScheduleOptions } from '../common/schedule/schedule.options';
|
||||||
|
|
||||||
export const getBackstageOptions = (
|
export const getBackstageOptions = (
|
||||||
timeFormat: string,
|
timeFormat: string,
|
||||||
customFields: CustomFields,
|
customFields: CustomFields,
|
||||||
projectData: ProjectData,
|
projectData: ProjectData,
|
||||||
): ViewOption[] => {
|
): ViewOption[] => {
|
||||||
|
const customFieldOptions = makeOptionsFromCustomFields(customFields, []);
|
||||||
const secondaryOptions = makeOptionsFromCustomFields(customFields, [
|
const secondaryOptions = makeOptionsFromCustomFields(customFields, [
|
||||||
{ value: 'none', label: 'None' },
|
{ value: 'none', label: 'None' },
|
||||||
{ value: 'note', label: 'Note' },
|
{ value: 'note', label: 'Note' },
|
||||||
@@ -39,7 +40,7 @@ export const getBackstageOptions = (
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
scheduleOptions,
|
getScheduleOptions(customFieldOptions),
|
||||||
{
|
{
|
||||||
title: OptionTitle.ElementVisibility,
|
title: OptionTitle.ElementVisibility,
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
import {
|
import { createContext, PropsWithChildren, RefObject, use, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||||
createContext,
|
import { EntryId, isOntimeEvent, OntimeEntry, OntimeEvent } from 'ontime-types';
|
||||||
PropsWithChildren,
|
|
||||||
RefObject,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useLayoutEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import { isOntimeEvent, OntimeEntry, OntimeEvent } from 'ontime-types';
|
|
||||||
|
|
||||||
import { usePartialRundown } from '../../../common/hooks-query/useRundown';
|
import { usePartialRundown } from '../../../common/hooks-query/useRundown';
|
||||||
|
|
||||||
@@ -25,13 +16,18 @@ interface ScheduleContextState {
|
|||||||
const ScheduleContext = createContext<ScheduleContextState | undefined>(undefined);
|
const ScheduleContext = createContext<ScheduleContextState | undefined>(undefined);
|
||||||
|
|
||||||
interface ScheduleProviderProps {
|
interface ScheduleProviderProps {
|
||||||
selectedEventId: string | null;
|
selectedEventId: EntryId | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ScheduleProvider = ({ children, selectedEventId }: PropsWithChildren<ScheduleProviderProps>) => {
|
export const ScheduleProvider = ({ children, selectedEventId }: PropsWithChildren<ScheduleProviderProps>) => {
|
||||||
const { cycleInterval, stopCycle } = useScheduleOptions();
|
const { cycleInterval, stopCycle, filter } = useScheduleOptions();
|
||||||
const { data: events } = usePartialRundown((event: OntimeEntry) => {
|
const { data: events } = usePartialRundown((entry: OntimeEntry) => {
|
||||||
return isOntimeEvent(event);
|
if (filter) {
|
||||||
|
// custom keys are prepended with custom-
|
||||||
|
const customKey = filter.startsWith('custom-') ? filter.slice('custom-'.length) : filter;
|
||||||
|
return isOntimeEvent(entry) && Boolean(entry.custom[customKey]);
|
||||||
|
}
|
||||||
|
return isOntimeEvent(entry);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [firstIndex, setFirstIndex] = useState(-1);
|
const [firstIndex, setFirstIndex] = useState(-1);
|
||||||
@@ -135,7 +131,7 @@ export const ScheduleProvider = ({ children, selectedEventId }: PropsWithChildre
|
|||||||
selectedEventIndex = 0;
|
selectedEventIndex = 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScheduleContext.Provider
|
<ScheduleContext
|
||||||
value={{
|
value={{
|
||||||
events: viewEvents as OntimeEvent[],
|
events: viewEvents as OntimeEvent[],
|
||||||
selectedEventId,
|
selectedEventId,
|
||||||
@@ -145,12 +141,12 @@ export const ScheduleProvider = ({ children, selectedEventId }: PropsWithChildre
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</ScheduleContext.Provider>
|
</ScheduleContext>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSchedule = () => {
|
export const useSchedule = () => {
|
||||||
const context = useContext(ScheduleContext);
|
const context = use(ScheduleContext);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error('useSchedule() can only be used inside a ScheduleContext');
|
throw new Error('useSchedule() can only be used inside a ScheduleContext');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useSearchParams } from 'react-router';
|
import { useSearchParams } from 'react-router';
|
||||||
|
|
||||||
|
import { SelectOption } from '../../../common/components/select/Select';
|
||||||
import { OptionTitle } from '../../../common/components/view-params-editor/constants';
|
import { OptionTitle } from '../../../common/components/view-params-editor/constants';
|
||||||
import { ViewOption } from '../../../common/components/view-params-editor/viewParams.types';
|
import type { ViewOption } from '../../../common/components/view-params-editor/viewParams.types';
|
||||||
import { isStringBoolean } from '../../../features/viewers/common/viewUtils';
|
import { isStringBoolean } from '../../../features/viewers/common/viewUtils';
|
||||||
|
|
||||||
export const scheduleOptions: ViewOption = {
|
export const getScheduleOptions = (customFieldOptions: SelectOption[]): ViewOption => ({
|
||||||
title: OptionTitle.Schedule,
|
title: OptionTitle.Schedule,
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
options: [
|
options: [
|
||||||
|
{
|
||||||
|
id: 'filter',
|
||||||
|
title: 'Filter',
|
||||||
|
description: 'Hide events without data in the selected custom field',
|
||||||
|
type: 'option',
|
||||||
|
values: customFieldOptions,
|
||||||
|
defaultValue: 'None',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'stopCycle',
|
id: 'stopCycle',
|
||||||
title: 'Stop cycling through event pages',
|
title: 'Stop cycling through event pages',
|
||||||
@@ -31,9 +40,10 @@ export const scheduleOptions: ViewOption = {
|
|||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
type ScheduleOptions = {
|
type ScheduleOptions = {
|
||||||
|
filter: string | null;
|
||||||
cycleInterval: number;
|
cycleInterval: number;
|
||||||
stopCycle: boolean;
|
stopCycle: boolean;
|
||||||
showExpected: boolean;
|
showExpected: boolean;
|
||||||
@@ -41,6 +51,7 @@ type ScheduleOptions = {
|
|||||||
|
|
||||||
function getScheduleOptionsFromParams(searchParams: URLSearchParams): ScheduleOptions {
|
function getScheduleOptionsFromParams(searchParams: URLSearchParams): ScheduleOptions {
|
||||||
return {
|
return {
|
||||||
|
filter: searchParams.get('filter'),
|
||||||
cycleInterval: Number(searchParams.get('cycleInterval')) || 10,
|
cycleInterval: Number(searchParams.get('cycleInterval')) || 10,
|
||||||
stopCycle: isStringBoolean(searchParams.get('stopCycle')),
|
stopCycle: isStringBoolean(searchParams.get('stopCycle')),
|
||||||
showExpected: isStringBoolean(searchParams.get('showExpected')),
|
showExpected: isStringBoolean(searchParams.get('showExpected')),
|
||||||
|
|||||||
Reference in New Issue
Block a user