From 2c8b6180d77f0bb86621b465b509afb3f479d3bb Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Mon, 17 Feb 2025 15:34:00 +0100 Subject: [PATCH] refactor: show menu only if enabled --- .../client/src/common/hooks/useEventAction.ts | 12 +++ .../cuesheet/cuesheet-table/CuesheetTable.tsx | 39 +++++---- .../cuesheet-table-elements/EventRow.tsx | 25 +++--- .../cuesheet-table-menu/CuesheetTableMenu.tsx | 79 ++++++++++--------- 4 files changed, 90 insertions(+), 65 deletions(-) diff --git a/apps/client/src/common/hooks/useEventAction.ts b/apps/client/src/common/hooks/useEventAction.ts index 8204b0709..3ebe479e5 100644 --- a/apps/client/src/common/hooks/useEventAction.ts +++ b/apps/client/src/common/hooks/useEventAction.ts @@ -55,6 +55,17 @@ export const useEventAction = () => { defaultEndAction, } = useEditorSettings(); + const getEventById = useCallback( + (eventId: string) => { + const cachedRundown = queryClient.getQueryData(RUNDOWN); + if (!cachedRundown?.rundown) { + return; + } + return cachedRundown.rundown[eventId]; + }, + [queryClient], + ); + /** * Calls mutation to add new event * @private @@ -615,6 +626,7 @@ export const useEventAction = () => { batchUpdateEvents, deleteEvent, deleteAllEvents, + getEventById, reorderEvent, swapEvents, updateEvent, diff --git a/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx b/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx index 230cd047a..d2121ca4d 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx @@ -1,5 +1,4 @@ import { useRef } from 'react'; -import { Menu } from '@chakra-ui/react'; import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import Color from 'color'; import { @@ -23,7 +22,6 @@ import BlockRow from './cuesheet-table-elements/BlockRow'; import CuesheetHeader from './cuesheet-table-elements/CuesheetHeader'; import DelayRow from './cuesheet-table-elements/DelayRow'; import EventRow from './cuesheet-table-elements/EventRow'; -import CuesheetTableMenu from './cuesheet-table-menu/CuesheetTableMenu'; import CuesheetTableSettings from './cuesheet-table-settings/CuesheetTableSettings'; import useColumnManager from './useColumnManager'; @@ -165,24 +163,25 @@ export default function CuesheetTable(props: CuesheetTableProps) { } return ( - - - {row.getVisibleCells().map((cell) => { - return ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ); - })} - - - + + {row.getVisibleCells().map((cell) => { + return ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ); + })} + ); } diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx index b2ebf2420..bb666cb3b 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx @@ -1,23 +1,27 @@ import { memo, MutableRefObject, PropsWithChildren, useLayoutEffect, useRef, useState } from 'react'; -import { IconButton, MenuButton } from '@chakra-ui/react'; +import { IconButton, Menu, MenuButton } from '@chakra-ui/react'; import { IoEllipsisHorizontal } from '@react-icons/all-files/io5/IoEllipsisHorizontal'; import Color from 'color'; import { cx, getAccessibleColour } from '../../../../common/utils/styleUtils'; import { useCuesheetOptions } from '../../cuesheet.options'; +import CuesheetTableMenu from '../cuesheet-table-menu/CuesheetTableMenu'; import style from '../CuesheetTable.module.scss'; interface EventRowProps { + eventId: string; eventIndex: number; + rowIndex: number; isPast?: boolean; selectedRef?: MutableRefObject; skip?: boolean; colour?: string; + showModal: (eventId: string) => void; } function EventRow(props: PropsWithChildren) { - const { children, eventIndex, isPast, selectedRef, skip, colour } = props; + const { children, eventId, eventIndex, rowIndex, isPast, selectedRef, skip, colour, showModal } = props; const { hideIndexColumn, showActionMenu } = useCuesheetOptions(); const ownRef = useRef(null); const [isVisible, setIsVisible] = useState(false); @@ -60,13 +64,16 @@ function EventRow(props: PropsWithChildren) { > {showActionMenu && ( - } - variant='ontime-subtle' - /> + + } + variant='ontime-subtle' + /> + + )} {!hideIndexColumn && ( diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/CuesheetTableMenu.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/CuesheetTableMenu.tsx index ff8082a9f..ffa94caac 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/CuesheetTableMenu.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/CuesheetTableMenu.tsx @@ -1,63 +1,70 @@ -import { MenuDivider, MenuItem, MenuList } from '@chakra-ui/react'; +import { MenuDivider, MenuItem, MenuList, Portal } from '@chakra-ui/react'; import { IoAdd } from '@react-icons/all-files/io5/IoAdd'; import { IoArrowDown } from '@react-icons/all-files/io5/IoArrowDown'; import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp'; import { IoDuplicateOutline } from '@react-icons/all-files/io5/IoDuplicateOutline'; import { IoOptions } from '@react-icons/all-files/io5/IoOptions'; import { IoTrash } from '@react-icons/all-files/io5/IoTrash'; -import { OntimeEvent, SupportedEvent } from 'ontime-types'; +import { isOntimeEvent, SupportedEvent } from 'ontime-types'; import { useEventAction } from '../../../../common/hooks/useEventAction'; import { cloneEvent } from '../../../../common/utils/eventsManager'; interface CuesheetTableMenuProps { - event: OntimeEvent; + eventId: string; entryIndex: number; showModal: (entryId: string) => void; } export default function CuesheetTableMenu(props: CuesheetTableMenuProps) { - const { event, entryIndex, showModal } = props; - const { addEvent, reorderEvent, deleteEvent } = useEventAction(); + const { eventId, entryIndex, showModal } = props; + const { addEvent, getEventById, reorderEvent, deleteEvent } = useEventAction(); const handleCloneEvent = () => { - const newEvent = cloneEvent(event); + const currentEvent = getEventById(eventId); + if (!currentEvent || !isOntimeEvent(currentEvent)) { + return; + } + + const newEvent = cloneEvent(currentEvent); try { - addEvent(newEvent, { after: event.id }); + addEvent(newEvent, { after: eventId }); } catch (_error) { // we do not handle errors here } }; return ( - - } onClick={() => showModal(event.id)}> - Edit ... - - - } onClick={() => addEvent({ type: SupportedEvent.Event }, { before: event.id })}> - Add event above - - } onClick={() => addEvent({ type: SupportedEvent.Event }, { after: event.id })}> - Add event below - - } onClick={handleCloneEvent}> - Clone event - - - } - onClick={() => reorderEvent(event.id, entryIndex, entryIndex - 1)} - > - Move up - - } onClick={() => reorderEvent(event.id, entryIndex, entryIndex + 1)}> - Move down - - } onClick={() => deleteEvent([event.id])}> - Delete - - + + + } onClick={() => showModal(eventId)}> + Edit ... + + + } onClick={() => addEvent({ type: SupportedEvent.Event }, { before: eventId })}> + Add event above + + } onClick={() => addEvent({ type: SupportedEvent.Event }, { after: eventId })}> + Add event below + + } onClick={handleCloneEvent}> + Clone event + + + } + onClick={() => reorderEvent(eventId, entryIndex, entryIndex - 1)} + > + Move up + + } onClick={() => reorderEvent(eventId, entryIndex, entryIndex + 1)}> + Move down + + } onClick={() => deleteEvent([eventId])}> + Delete + + + ); }