import { use, useMemo } from 'react'; import { useSearchParams } from 'react-router'; import { CustomFields, EntryId, OntimeEvent } from 'ontime-types'; import { getTimeOption } from '../../common/components/view-params-editor/common.options'; import { OptionTitle } from '../../common/components/view-params-editor/constants'; import { ViewOption } from '../../common/components/view-params-editor/viewParams.types'; import { makeCustomFieldSelectOptions, makeOptionsFromCustomFields, } from '../../common/components/view-params-editor/viewParams.utils'; import { PresetContext } from '../../common/context/PresetContext'; import { isStringBoolean } from '../../views/common/viewUtils'; export const getOperatorOptions = (customFields: CustomFields, timeFormat: string): ViewOption[] => { const fieldOptions = makeOptionsFromCustomFields(customFields, [ { value: 'none', label: 'None' }, { value: 'title', label: 'Title' }, { value: 'note', label: 'Note' }, ]); const customFieldSelect = makeCustomFieldSelectOptions(customFields); return [ { title: OptionTitle.ClockOptions, collapsible: true, options: [getTimeOption(timeFormat)] }, { title: OptionTitle.DataSources, collapsible: true, options: [ { id: 'main', title: 'Main data field', description: 'Field to be shown in the first line of text', type: 'option', values: fieldOptions, defaultValue: 'title', }, { id: 'secondary-src', title: 'Secondary data field', description: 'Field to be shown in the second line of text', type: 'option', values: fieldOptions, defaultValue: 'none', }, { id: 'subscribe', title: 'Highlight Fields', description: 'Choose custom fields to highlight', type: 'multi-option', values: customFieldSelect, }, { id: 'shouldEdit', title: 'Edit custom field', description: 'Allows editing an highlighted custom field by long pressing', type: 'boolean', defaultValue: false, }, ], }, { title: OptionTitle.ElementVisibility, collapsible: true, options: [ { id: 'hidePast', title: 'Hide Past Events', description: 'Whether to hide events that have passed', type: 'boolean', defaultValue: false, }, { id: 'showStart', title: 'Show planned start', description: 'Whether to prepend the planned start to the items', type: 'boolean', defaultValue: false, }, ], }, ]; }; type OperatorOptions = { mainSource: keyof OntimeEvent | null; secondarySource: keyof OntimeEvent | null; subscribe: string[]; shouldEdit: boolean; hidePast: boolean; showStart: boolean; }; /** * Utility extract the view options from URL Params * the names and fallback are manually matched with timerOptions */ function getOptionsFromParams(searchParams: URLSearchParams, defaultValues?: URLSearchParams): OperatorOptions { // Helper to get value from either source, prioritizing defaultValues const getValue = (key: string) => defaultValues?.get(key) ?? searchParams.get(key); // Helper to get array values from either source const getArrayValues = (key: string): EntryId[] => { if (defaultValues?.has(key)) { return defaultValues.getAll(key) as EntryId[]; } return searchParams.getAll(key) as EntryId[]; }; // we manually make an object that matches the key above return { mainSource: getValue('main') as keyof OntimeEvent | null, secondarySource: getValue('secondary-src') as keyof OntimeEvent | null, subscribe: getArrayValues('subscribe'), shouldEdit: isStringBoolean(getValue('shouldEdit')), hidePast: isStringBoolean(getValue('hidePast')), showStart: isStringBoolean(getValue('showStart')), }; } /** * Hook exposes the operator view options */ export function useOperatorOptions(): OperatorOptions { const [searchParams] = useSearchParams(); const maybePreset = use(PresetContext); const options = useMemo(() => { const defaultValues = maybePreset ? new URLSearchParams(maybePreset.search) : undefined; return getOptionsFromParams(searchParams, defaultValues); }, [maybePreset, searchParams]); return options; }