From 8116b169b284ba696598aaf8143a134a389454dd Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Tue, 17 Dec 2024 13:22:47 +0100 Subject: [PATCH] refactor: generalise event editor --- .../src/features/rundown/RundownExport.tsx | 4 +- .../event-editor/CuesheetEventEditor.tsx | 44 ++++++++++++++++ .../event-editor/RundownEventEditor.tsx | 50 +++++++++++++++++++ .../composite/EventEditorFooter.module.scss | 7 +++ .../composite/EventEditorFooter.tsx | 30 +++++++++++ 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 apps/client/src/features/rundown/event-editor/CuesheetEventEditor.tsx create mode 100644 apps/client/src/features/rundown/event-editor/RundownEventEditor.tsx create mode 100644 apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.module.scss create mode 100644 apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.tsx diff --git a/apps/client/src/features/rundown/RundownExport.tsx b/apps/client/src/features/rundown/RundownExport.tsx index 272d8d932..69cada24f 100644 --- a/apps/client/src/features/rundown/RundownExport.tsx +++ b/apps/client/src/features/rundown/RundownExport.tsx @@ -7,7 +7,7 @@ import { handleLinks } from '../../common/utils/linkUtils'; import { cx } from '../../common/utils/styleUtils'; import { Corner } from '../editors/editor-utils/EditorUtils'; -import EventEditor from './event-editor/EventEditor'; +import RundownEventEditor from './event-editor/RundownEventEditor'; import RundownWrapper from './RundownWrapper'; import style from './RundownExport.module.scss'; @@ -33,7 +33,7 @@ const RundownExport = () => { {!hideSideBar && (
- +
)} diff --git a/apps/client/src/features/rundown/event-editor/CuesheetEventEditor.tsx b/apps/client/src/features/rundown/event-editor/CuesheetEventEditor.tsx new file mode 100644 index 000000000..f6a75d159 --- /dev/null +++ b/apps/client/src/features/rundown/event-editor/CuesheetEventEditor.tsx @@ -0,0 +1,44 @@ +import { useEffect, useState } from 'react'; +import { isOntimeEvent, OntimeEvent } from 'ontime-types'; + +import useRundown from '../../../common/hooks-query/useRundown'; + +import EventEditor from './EventEditor'; + +import style from './EventEditor.module.scss'; + +interface CuesheetEventEditorProps { + eventId: string; +} + +export default function CuesheetEventEditor(props: CuesheetEventEditorProps) { + const { eventId } = props; + const { data } = useRundown(); + const { order, rundown } = data; + + const [event, setEvent] = useState(null); + + useEffect(() => { + if (order.length === 0) { + setEvent(null); + return; + } + + const event = rundown[eventId]; + if (event && isOntimeEvent(event)) { + setEvent(event); + } else { + setEvent(null); + } + }, [data, eventId, order, rundown]); + + if (!event) { + return null; + } + + return ( +
+ +
+ ); +} diff --git a/apps/client/src/features/rundown/event-editor/RundownEventEditor.tsx b/apps/client/src/features/rundown/event-editor/RundownEventEditor.tsx new file mode 100644 index 000000000..f21f5a0ed --- /dev/null +++ b/apps/client/src/features/rundown/event-editor/RundownEventEditor.tsx @@ -0,0 +1,50 @@ +import { useEffect, useState } from 'react'; +import { isOntimeEvent, OntimeEvent } from 'ontime-types'; + +import useRundown from '../../../common/hooks-query/useRundown'; +import { useEventSelection } from '../useEventSelection'; + +import { EventEditorFooter } from './composite/EventEditorFooter'; +import EventEditor from './EventEditor'; +import EventEditorEmpty from './EventEditorEmpty'; + +import style from './EventEditor.module.scss'; + +export default function RundownEventEditor() { + const selectedEvents = useEventSelection((state) => state.selectedEvents); + const { data } = useRundown(); + const { order, rundown } = data; + + const [event, setEvent] = useState(null); + + useEffect(() => { + if (order.length === 0) { + setEvent(null); + return; + } + + const selectedEventId = order.find((eventId) => selectedEvents.has(eventId)); + if (!selectedEventId) { + setEvent(null); + return; + } + const event = rundown[selectedEventId]; + + if (event && isOntimeEvent(event)) { + setEvent(event); + } else { + setEvent(null); + } + }, [order, rundown, selectedEvents]); + + if (!event) { + return ; + } + + return ( +
+ + +
+ ); +} diff --git a/apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.module.scss b/apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.module.scss new file mode 100644 index 000000000..4d94a737e --- /dev/null +++ b/apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.module.scss @@ -0,0 +1,7 @@ +.footer { + border-top: 1px solid $white-10; + padding-top: 1rem; + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} diff --git a/apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.tsx b/apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.tsx new file mode 100644 index 000000000..aa20e9e38 --- /dev/null +++ b/apps/client/src/features/rundown/event-editor/composite/EventEditorFooter.tsx @@ -0,0 +1,30 @@ +import { memo } from 'react'; + +import CopyTag from '../../../../common/components/copy-tag/CopyTag'; + +import style from './EventEditorFooter.module.scss'; + +interface EventEditorFooterProps { + id: string; + cue: string; +} + +export const EventEditorFooter = memo(_EventEditorFooter); + +function _EventEditorFooter(props: EventEditorFooterProps) { + const { id, cue } = props; + + const loadById = `/ontime/load/id "${id}"`; + const loadByCue = `/ontime/load/cue "${cue}"`; + + return ( +
+ + {loadById} + + + {loadByCue} + +
+ ); +}