Default Values in ParamEditor (#610)

* add `defaultvalue` to `Field` types

* add `defaultValue` to constants; turn into functions for time values

* update constant imports/calls in view components

* use `defaultValue`s in `ParamInput`

* change `Clear` to `Reset`to better reflect actions

* make `defaultValue` optional rather than `undefined`

* update forgotten constants

* add `defaultValue` to boolean input

* change `101010` to `000000`

* add `prefix` property to types

* implement `prefix` for `ParamInput`s

* change `paramField` to `prop`

* add `onEditDrawerClose` to `resetParams`

* `ViewParamsEditor` omits default values

* undo close on reset

* move `useSettings` into `ViewWrapper`

* change `settings` to include `undefined`
This commit is contained in:
asharonbaltazar
2023-11-26 15:57:18 -05:00
committed by GitHub
parent f2504072ce
commit edb79d5819
12 changed files with 180 additions and 72 deletions
@@ -11,6 +11,7 @@ import useFollowComponent from '../../common/hooks/useFollowComponent';
import { useOperator } from '../../common/hooks/useSocket';
import useProjectData from '../../common/hooks-query/useProjectData';
import useRundown from '../../common/hooks-query/useRundown';
import useSettings from '../../common/hooks-query/useSettings';
import useUserFields from '../../common/hooks-query/useUserFields';
import { debounce } from '../../common/utils/debounce';
import { isStringBoolean } from '../../common/utils/viewUtils';
@@ -40,6 +41,7 @@ export default function Operator() {
const featureData = useOperator();
const [searchParams] = useSearchParams();
const { data: settings } = useSettings();
const [showEditPrompt, setShowEditPrompt] = useState(false);
const [editEvent, setEditEvent] = useState<PartialEdit | null>(null);
@@ -127,7 +129,7 @@ export default function Operator() {
const subscribedAlias = subscribe ? userFields[subscribe] : '';
const showSeconds = isStringBoolean(searchParams.get('showseconds'));
const operatorOptions = getOperatorOptions(userFields);
const operatorOptions = getOperatorOptions(userFields, settings?.timeFormat ?? '24');
let isPast = Boolean(featureData.selectedEventId);
const hidePast = isStringBoolean(searchParams.get('hidepast'));
@@ -1,10 +1,11 @@
import { ComponentType, useMemo } from 'react';
import { TimeManagerType } from 'common/models/TimeManager.type';
import { Message, OntimeEvent, ProjectData, SupportedEvent, TimerMessage, ViewSettings } from 'ontime-types';
import { Message, OntimeEvent, ProjectData, Settings, SupportedEvent, TimerMessage, ViewSettings } from 'ontime-types';
import { useStore } from 'zustand';
import useProjectData from '../../common/hooks-query/useProjectData';
import useRundown from '../../common/hooks-query/useRundown';
import useSettings from '../../common/hooks-query/useSettings';
import useViewSettings from '../../common/hooks-query/useViewSettings';
import { runtime } from '../../common/stores/runtime';
import { useViewOptionsStore } from '../../common/stores/viewOptions';
@@ -27,6 +28,7 @@ type WithDataProps = {
nextId: string | null;
general: ProjectData;
viewSettings: ViewSettings;
settings: Settings | undefined;
onAir: boolean;
};
@@ -43,6 +45,7 @@ const withData = <P extends WithDataProps>(Component: ComponentType<P>) => {
const { data: rundownData } = useRundown();
const { data: project } = useProjectData();
const { data: viewSettings } = useViewSettings();
const { data: settings } = useSettings();
const publicEvents = useMemo(() => {
if (Array.isArray(rundownData)) {
@@ -104,6 +107,7 @@ const withData = <P extends WithDataProps>(Component: ComponentType<P>) => {
selectedId={selectedId}
publicSelectedId={publicSelectedId}
viewSettings={viewSettings}
settings={settings}
nextId={nextId}
general={project}
onAir={onAir}
@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import QRCode from 'react-qr-code';
import { AnimatePresence, motion } from 'framer-motion';
import { Message, OntimeEvent, ProjectData, SupportedEvent, ViewSettings } from 'ontime-types';
import { Message, OntimeEvent, ProjectData, Settings, SupportedEvent, ViewSettings } from 'ontime-types';
import { formatDisplay } from 'ontime-utils';
import { overrideStylesURL } from '../../../common/api/apiConstants';
@@ -11,7 +11,7 @@ import Schedule from '../../../common/components/schedule/Schedule';
import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext';
import ScheduleNav from '../../../common/components/schedule/ScheduleNav';
import TitleCard from '../../../common/components/title-card/TitleCard';
import { BACKSTAGE_OPTIONS } from '../../../common/components/view-params-editor/constants';
import { getBackstageOptions } from '../../../common/components/view-params-editor/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TimeManagerType } from '../../../common/models/TimeManager.type';
@@ -37,10 +37,12 @@ interface BackstageProps {
selectedId: string | null;
general: ProjectData;
viewSettings: ViewSettings;
settings: Settings | undefined;
}
export default function Backstage(props: BackstageProps) {
const { isMirrored, publ, eventNow, eventNext, time, backstageEvents, selectedId, general, viewSettings } = props;
const { isMirrored, publ, eventNow, eventNext, time, backstageEvents, selectedId, general, viewSettings, settings } =
props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const { getLocalizedString } = useTranslation();
const [blinkClass, setBlinkClass] = useState(false);
@@ -89,11 +91,12 @@ export default function Backstage(props: BackstageProps) {
}
const totalTime = (time.duration ?? 0) + (time.addedTime ?? 0);
const backstageOptions = getBackstageOptions(settings?.timeFormat ?? '24');
return (
<div className={`backstage ${isMirrored ? 'mirror' : ''}`} data-testid='backstage-view'>
<NavigationMenu />
<ViewParamsEditor paramFields={BACKSTAGE_OPTIONS} />
<ViewParamsEditor paramFields={backstageOptions} />
<div className='project-header'>
{general.title}
<div className='clock-container'>
@@ -1,10 +1,10 @@
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { ViewSettings } from 'ontime-types';
import { Settings, ViewSettings } from 'ontime-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import { CLOCK_OPTIONS } from '../../../common/components/view-params-editor/constants';
import { getClockOptions } from '../../../common/components/view-params-editor/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TimeManagerType } from '../../../common/models/TimeManager.type';
@@ -18,6 +18,7 @@ interface ClockProps {
isMirrored: boolean;
time: TimeManagerType;
viewSettings: ViewSettings;
settings: Settings | undefined;
}
const formatOptions = {
@@ -26,7 +27,7 @@ const formatOptions = {
};
export default function Clock(props: ClockProps) {
const { isMirrored, time, viewSettings } = props;
const { isMirrored, time, viewSettings, settings } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const [searchParams] = useSearchParams();
@@ -124,6 +125,8 @@ export default function Clock(props: ClockProps) {
const clock = formatTime(time.clock, formatOptions);
const clean = clock.replace('/:/g', '');
const clockOptions = getClockOptions(settings?.timeFormat ?? '24');
return (
<div
className={`clock-view ${isMirrored ? 'mirror' : ''}`}
@@ -135,7 +138,7 @@ export default function Clock(props: ClockProps) {
data-testid='clock-view'
>
<NavigationMenu />
<ViewParamsEditor paramFields={CLOCK_OPTIONS} />
<ViewParamsEditor paramFields={clockOptions} />
<SuperscriptTime
time={clock}
className='clock'
@@ -1,11 +1,11 @@
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { OntimeEvent, OntimeRundownEntry, Playback, SupportedEvent, ViewSettings } from 'ontime-types';
import { OntimeEvent, OntimeRundownEntry, Playback, Settings, SupportedEvent, ViewSettings } from 'ontime-types';
import { formatDisplay } from 'ontime-utils';
import { overrideStylesURL } from '../../../common/api/apiConstants';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import { TIME_FORMAT_OPTION } from '../../../common/components/view-params-editor/constants';
import { getTimeOption } from '../../../common/components/view-params-editor/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TimeManagerType } from '../../../common/models/TimeManager.type';
@@ -34,10 +34,11 @@ interface CountdownProps {
time: TimeManagerType;
selectedId: string | null;
viewSettings: ViewSettings;
settings: Settings | undefined;
}
export default function Countdown(props: CountdownProps) {
const { isMirrored, backstageEvents, time, selectedId, viewSettings } = props;
const { isMirrored, backstageEvents, time, selectedId, viewSettings, settings } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const [searchParams] = useSearchParams();
const { getLocalizedString } = useTranslation();
@@ -109,10 +110,12 @@ export default function Countdown(props: CountdownProps) {
isSelected || runningMessage === TimerMessage.waiting,
);
const timeOption = getTimeOption(settings?.timeFormat ?? '24');
return (
<div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'>
<NavigationMenu />
<ViewParamsEditor paramFields={[TIME_FORMAT_OPTION]} />
<ViewParamsEditor paramFields={[timeOption]} />
{follow === null ? (
<CountdownSelect events={backstageEvents} />
) : (
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import QRCode from 'react-qr-code';
import { AnimatePresence, motion } from 'framer-motion';
import { Message, OntimeEvent, ProjectData, ViewSettings } from 'ontime-types';
import { Message, OntimeEvent, ProjectData, Settings, ViewSettings } from 'ontime-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
@@ -9,7 +9,7 @@ import Schedule from '../../../common/components/schedule/Schedule';
import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext';
import ScheduleNav from '../../../common/components/schedule/ScheduleNav';
import TitleCard from '../../../common/components/title-card/TitleCard';
import { PUBLIC_OPTIONS } from '../../../common/components/view-params-editor/constants';
import { getPublicOptions } from '../../../common/components/view-params-editor/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TimeManagerType } from '../../../common/models/TimeManager.type';
@@ -35,11 +35,22 @@ interface BackstageProps {
publicSelectedId: string | null;
general: ProjectData;
viewSettings: ViewSettings;
settings: Settings | undefined;
}
export default function Public(props: BackstageProps) {
const { isMirrored, publ, publicEventNow, publicEventNext, time, events, publicSelectedId, general, viewSettings } =
props;
const {
isMirrored,
publ,
publicEventNow,
publicEventNext,
time,
events,
publicSelectedId,
general,
viewSettings,
settings,
} = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const { getLocalizedString } = useTranslation();
@@ -56,10 +67,12 @@ export default function Public(props: BackstageProps) {
const clock = formatTime(time.clock, formatOptions);
const qrSize = Math.max(window.innerWidth / 15, 128);
const publicOptions = getPublicOptions(settings?.timeFormat ?? '24');
return (
<div className={`public-screen ${isMirrored ? 'mirror' : ''}`} data-testid='public-view'>
<NavigationMenu />
<ViewParamsEditor paramFields={PUBLIC_OPTIONS} />
<ViewParamsEditor paramFields={publicOptions} />
<div className='project-header'>
{general.title}
<div className='clock-container'>
@@ -1,12 +1,12 @@
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import type { OntimeEvent, OntimeRundown, ViewSettings } from 'ontime-types';
import type { OntimeEvent, OntimeRundown, Settings, ViewSettings } from 'ontime-types';
import { SupportedEvent } from 'ontime-types';
import { formatDisplay } from 'ontime-utils';
import { overrideStylesURL } from '../../../common/api/apiConstants';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import { STUDIO_CLOCK_OPTIONS } from '../../../common/components/view-params-editor/constants';
import { getStudioClockOptions } from '../../../common/components/view-params-editor/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import useFitText from '../../../common/hooks/useFitText';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
@@ -32,10 +32,11 @@ interface StudioClockProps {
nextId: string | null;
onAir: boolean;
viewSettings: ViewSettings;
settings: Settings | undefined;
}
export default function StudioClock(props: StudioClockProps) {
const { isMirrored, eventNext, time, backstageEvents, selectedId, nextId, onAir, viewSettings } = props;
const { isMirrored, eventNext, time, backstageEvents, selectedId, nextId, onAir, viewSettings, settings } = props;
// deferring rendering seems to affect styling (font and useFitText)
useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
@@ -75,10 +76,12 @@ export default function StudioClock(props: StudioClockProps) {
const secondsNow = secondsInMillis(time.clock);
const isNegative = (time.current ?? 0) < 0;
const studioClockOptions = getStudioClockOptions(settings?.timeFormat ?? '24');
return (
<div className={`studio-clock ${isMirrored ? 'mirror' : ''}`} data-testid='studio-view'>
<NavigationMenu />
<ViewParamsEditor paramFields={STUDIO_CLOCK_OPTIONS} />
<ViewParamsEditor paramFields={studioClockOptions} />
<div className='clock-container'>
<div className={`studio-timer ${showSeconds ? 'studio-timer--with-seconds' : ''}`}>{clock}</div>
<div
@@ -1,13 +1,13 @@
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { AnimatePresence, motion } from 'framer-motion';
import { Message, OntimeEvent, Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
import { Message, OntimeEvent, Playback, Settings, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
import MultiPartProgressBar from '../../../common/components/multi-part-progress-bar/MultiPartProgressBar';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import TitleCard from '../../../common/components/title-card/TitleCard';
import { TIMER_OPTIONS } from '../../../common/components/view-params-editor/constants';
import { getTimerOptions } from '../../../common/components/view-params-editor/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TimeManagerType } from '../../../common/models/TimeManager.type';
@@ -48,10 +48,11 @@ interface TimerProps {
eventNext: OntimeEvent | null;
time: TimeManagerType;
viewSettings: ViewSettings;
settings: Settings | undefined;
}
export default function Timer(props: TimerProps) {
const { isMirrored, pres, eventNow, eventNext, time, viewSettings, external } = props;
const { isMirrored, pres, eventNow, eventNext, time, viewSettings, external, settings } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const { getLocalizedString } = useTranslation();
const [searchParams] = useSearchParams();
@@ -128,10 +129,12 @@ export default function Timer(props: TimerProps) {
const timerContainerClasses = `timer-container ${showBlinking ? (showOverlay ? '' : 'blink') : ''}`;
const timerClasses = `timer ${!isPlaying ? 'timer--paused' : ''} ${showFinished ? 'timer--finished' : ''}`;
const timerOptions = getTimerOptions(settings?.timeFormat ?? '24');
return (
<div className={showFinished ? `${baseClasses} stage-timer--finished` : baseClasses} data-testid='timer-view'>
<NavigationMenu />
<ViewParamsEditor paramFields={TIMER_OPTIONS} />
<ViewParamsEditor paramFields={timerOptions} />
{!userOptions.hideMessage && (
<div className={showOverlay ? 'message-overlay message-overlay--active' : 'message-overlay'}>
<div className={`message ${showBlinking ? 'blink' : ''}`}>{pres.text}</div>