mirror of
https://github.com/cpvalente/ontime.git
synced 2026-07-26 10:38:55 +00:00
feat: option to select all events for countdown
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { IoAdd } from 'react-icons/io5';
|
||||
import { EntryId, isOntimeEvent, isPlayableEvent, OntimeEvent, OntimeView } from 'ontime-types';
|
||||
import { isOntimeEvent, isPlayableEvent, OntimeEvent, OntimeView } from 'ontime-types';
|
||||
|
||||
import Button from '../../common/components/buttons/Button';
|
||||
import Empty from '../../common/components/state/Empty';
|
||||
@@ -16,7 +16,7 @@ import { useTranslation } from '../../translation/TranslationProvider';
|
||||
import Loader from '../common/loader/Loader';
|
||||
|
||||
import { getCountdownOptions, useCountdownOptions } from './countdown.options';
|
||||
import { getOrderedSubscriptions } from './countdown.utils';
|
||||
import { CountdownSubscription, getOrderedSubscriptions } from './countdown.utils';
|
||||
import CountdownSelect from './CountdownSelect';
|
||||
import CountdownSubscriptions from './CountdownSubscriptions';
|
||||
import SingleEventCountdown from './SingleEventCountdown';
|
||||
@@ -59,6 +59,8 @@ function Countdown({ customFields, rundownData, projectData, isMirrored, setting
|
||||
[defaultFormat, customFields, subscriptions],
|
||||
);
|
||||
|
||||
console.log(subscriptions)
|
||||
|
||||
return (
|
||||
<div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'>
|
||||
<ViewParamsEditor target={OntimeView.Countdown} viewOptions={countdownOptions} />
|
||||
@@ -87,7 +89,7 @@ function Countdown({ customFields, rundownData, projectData, isMirrored, setting
|
||||
|
||||
interface CountdownContentsProps {
|
||||
playableEvents: ExtendedEntry<OntimeEvent>[];
|
||||
subscriptions: EntryId[];
|
||||
subscriptions: CountdownSubscription;
|
||||
goToEditMode: () => void;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { IoArrowBack, IoClose, IoSaveOutline } from 'react-icons/io5';
|
||||
import { IoArrowBack, IoClose, IoSaveOutline, IoAlbumsOutline } from 'react-icons/io5';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { EntryId, OntimeEvent } from 'ontime-types';
|
||||
|
||||
@@ -7,18 +7,19 @@ import Button from '../../common/components/buttons/Button';
|
||||
import { cx } from '../../common/utils/styleUtils';
|
||||
import ClockTime from '../../features/viewers/common/clock-time/ClockTime';
|
||||
|
||||
import { makeSubscriptionsUrl } from './countdown.utils';
|
||||
import { CountdownSubscription, makeSubscriptionsUrl } from './countdown.utils';
|
||||
|
||||
import './Countdown.scss';
|
||||
|
||||
interface CountdownSelectProps {
|
||||
events: OntimeEvent[];
|
||||
subscriptions: EntryId[];
|
||||
subscriptions: CountdownSubscription;
|
||||
disableEdit: () => void;
|
||||
}
|
||||
|
||||
export default function CountdownSelect({ events, subscriptions, disableEdit }: CountdownSelectProps) {
|
||||
const [selected, setSelected] = useState<EntryId[]>(subscriptions);
|
||||
const maybeAllSubscriptions: EntryId[] = subscriptions === 'all' ? events.map((event) => event.id) : subscriptions;
|
||||
const [selected, setSelected] = useState<EntryId[]>(maybeAllSubscriptions);
|
||||
const navigate = useNavigate();
|
||||
|
||||
/**
|
||||
@@ -47,6 +48,18 @@ export default function CountdownSelect({ events, subscriptions, disableEdit }:
|
||||
navigate(url.search.toString());
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a URL with all
|
||||
* and navigates to it
|
||||
*/
|
||||
const applyAll = () => {
|
||||
// we remove events that no longer exist to avoid stale subscriptions
|
||||
const url = makeSubscriptionsUrl(window.location.href, 'all');
|
||||
disableEdit();
|
||||
setSelected([]);
|
||||
navigate(url.search.toString());
|
||||
};
|
||||
|
||||
// make a copy of the selected array for quick lookup
|
||||
const selectedIds = new Set(selected);
|
||||
|
||||
@@ -86,6 +99,10 @@ export default function CountdownSelect({ events, subscriptions, disableEdit }:
|
||||
<Button variant='subtle' size='xlarge' onClick={disableEdit}>
|
||||
<IoArrowBack /> Go back
|
||||
</Button>
|
||||
<Button variant='subtle' size='xlarge' onClick={applyAll}>
|
||||
{/* TODO: icon ??? */}
|
||||
<IoAlbumsOutline /> Use All
|
||||
</Button>
|
||||
<Button variant='subtle' size='xlarge' onClick={() => setSelected([])} disabled={selected.length === 0}>
|
||||
<IoClose /> Clear
|
||||
</Button>
|
||||
|
||||
@@ -8,11 +8,12 @@ import { ViewOption } from '../../common/components/view-params-editor/viewParam
|
||||
import { makeOptionsFromCustomFields } from '../../common/components/view-params-editor/viewParams.utils';
|
||||
import { PresetContext } from '../../common/context/PresetContext';
|
||||
import { isStringBoolean } from '../../features/viewers/common/viewUtils';
|
||||
import { CountdownSubscription } from './countdown.utils';
|
||||
|
||||
export const getCountdownOptions = (
|
||||
timeFormat: string,
|
||||
customFields: CustomFields,
|
||||
persistedSubscriptions: EntryId[],
|
||||
persistedSubscriptions: CountdownSubscription,
|
||||
): ViewOption[] => {
|
||||
const secondaryOptions = makeOptionsFromCustomFields(customFields, [
|
||||
{ value: 'none', label: 'None' },
|
||||
@@ -55,7 +56,7 @@ export const getCountdownOptions = (
|
||||
id: 'sub',
|
||||
title: 'Event subscription',
|
||||
description: 'The events to follow',
|
||||
values: persistedSubscriptions,
|
||||
values: persistedSubscriptions === 'all' ? ['all'] : persistedSubscriptions,
|
||||
type: 'persist',
|
||||
},
|
||||
],
|
||||
@@ -64,7 +65,7 @@ export const getCountdownOptions = (
|
||||
};
|
||||
|
||||
type CountdownOptions = {
|
||||
subscriptions: EntryId[];
|
||||
subscriptions: CountdownSubscription;
|
||||
secondarySource: keyof OntimeEvent | null;
|
||||
showExpected: boolean;
|
||||
};
|
||||
@@ -85,8 +86,10 @@ function getOptionsFromParams(searchParams: URLSearchParams, defaultValues?: URL
|
||||
return searchParams.getAll(key) as EntryId[];
|
||||
};
|
||||
|
||||
const subscriptions = getArrayValues('sub');
|
||||
|
||||
return {
|
||||
subscriptions: getArrayValues('sub'),
|
||||
subscriptions: subscriptions.at(0) === 'all' ? 'all' : subscriptions,
|
||||
secondarySource: getValue('secondary-src') as keyof OntimeEvent | null,
|
||||
showExpected: isStringBoolean(getValue('showExpected')),
|
||||
};
|
||||
|
||||
@@ -14,6 +14,8 @@ export function sanitiseTitle(title: string | null) {
|
||||
return title ?? '{no title}';
|
||||
}
|
||||
|
||||
export type CountdownSubscription = EntryId[] | 'all';
|
||||
|
||||
export const preferredFormat12 = 'h:mm a';
|
||||
export const preferredFormat24 = 'HH:mm';
|
||||
|
||||
@@ -120,7 +122,7 @@ export function useSubscriptionDisplayData(
|
||||
/**
|
||||
* Adds a set of subscriptions to the URL parameters
|
||||
*/
|
||||
export function makeSubscriptionsUrl(urlRef: string, subscriptions: EntryId[]) {
|
||||
export function makeSubscriptionsUrl(urlRef: string, subscriptions: CountdownSubscription) {
|
||||
const url = new URL(urlRef);
|
||||
const newParams = new URLSearchParams();
|
||||
|
||||
@@ -131,10 +133,14 @@ export function makeSubscriptionsUrl(urlRef: string, subscriptions: EntryId[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// add new subscriptions
|
||||
subscriptions.forEach((id) => {
|
||||
newParams.append('sub', id);
|
||||
});
|
||||
if (subscriptions === 'all') {
|
||||
newParams.append('sub', 'all');
|
||||
} else {
|
||||
// add new subscriptions
|
||||
subscriptions.forEach((id) => {
|
||||
newParams.append('sub', id);
|
||||
});
|
||||
}
|
||||
|
||||
url.search = newParams.toString();
|
||||
|
||||
@@ -146,7 +152,11 @@ export function makeSubscriptionsUrl(urlRef: string, subscriptions: EntryId[]) {
|
||||
* Since the original array is already ordered, we simply filter out the events
|
||||
* which are not in the subscriptions list.
|
||||
*/
|
||||
export function getOrderedSubscriptions<T extends OntimeEntry>(subscriptions: EntryId[], playableEvents: T[]): T[] {
|
||||
export function getOrderedSubscriptions<T extends OntimeEntry>(
|
||||
subscriptions: CountdownSubscription,
|
||||
playableEvents: T[],
|
||||
): T[] {
|
||||
if (subscriptions === 'all') return playableEvents;
|
||||
return playableEvents.filter((event) => subscriptions.includes(event.id));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user