refactor: countdown view redesign

- allow selecting multiple events
- follow selected
- remove past events
This commit is contained in:
Carlos Valente
2025-06-03 21:45:17 +02:00
committed by Carlos Valente
parent 93977ebc48
commit b2b115c329
22 changed files with 955 additions and 672 deletions
@@ -0,0 +1,83 @@
import { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { CustomFields, EntryId, OntimeEvent } from 'ontime-types';
import {
getTimeOption,
makeOptionsFromCustomFields,
OptionTitle,
} from '../../common/components/view-params-editor/constants';
import { ViewOption } from '../../common/components/view-params-editor/types';
import { isStringBoolean } from '../../features/viewers/common/viewUtils';
export const getCountdownOptions = (timeFormat: string, customFields: CustomFields): ViewOption[] => {
const secondaryOptions = makeOptionsFromCustomFields(customFields, { note: 'Note' });
return [
{ title: OptionTitle.ClockOptions, collapsible: true, options: [getTimeOption(timeFormat)] },
{
title: OptionTitle.DataSources,
collapsible: true,
options: [
{
id: 'sub',
title: 'Event subscription',
description: 'The events to follow',
value: '',
type: 'persist',
},
{
// TODO: adding a secondary source is removing the subscriptions
// this seems to be a bug with persist assuming that the property has a single entry
id: 'secondary-src',
title: 'Event secondary text',
description: 'Select the data source for auxiliary text shown in the card',
type: 'option',
values: secondaryOptions,
defaultValue: '',
},
],
},
{
title: OptionTitle.BehaviourOptions,
collapsible: true,
options: [
{
id: 'showProjected',
title: 'Show projected time',
description: 'Whether scheduled times should account for runtime offset',
type: 'boolean',
defaultValue: false,
},
],
},
];
};
type CountdownOptions = {
subscriptions: EntryId[];
secondarySource: keyof OntimeEvent | null;
showProjected: boolean;
};
/**
* Utility extract the view options from URL Params
* the names and fallback are manually matched with timerOptions
*/
function getOptionsFromParams(searchParams: URLSearchParams): CountdownOptions {
// we manually make an object that matches the key above
return {
subscriptions: searchParams.getAll('sub') as EntryId[],
secondarySource: searchParams.get('secondary-src') as keyof OntimeEvent | null,
showProjected: isStringBoolean(searchParams.get('showProjected')),
};
}
/**
* Hook exposes the backstage view options
*/
export function useCountdownOptions(): CountdownOptions {
const [searchParams] = useSearchParams();
const options = useMemo(() => getOptionsFromParams(searchParams), [searchParams]);
return options;
}