refactor: review action menu

This commit is contained in:
Carlos Valente
2025-07-08 06:45:22 +02:00
committed by Carlos Valente
parent 9281c0b51d
commit a1ad1d47a4
9 changed files with 227 additions and 61 deletions
@@ -1,8 +1,8 @@
import { memo } from 'react';
import { IoAdd, IoArrowDown, IoArrowUp, IoDuplicateOutline, IoOptions, IoTrash } from 'react-icons/io5';
import { Menu, MenuButton, MenuDivider, MenuItem, MenuList, Portal } from '@chakra-ui/react';
import { SupportedEntry } from 'ontime-types';
import Menu from '../../../../common/components/dropdown-menu/DropdownMenu';
import { useEntryActions } from '../../../../common/hooks/useEntryAction';
import { useCuesheetEditModal } from '../../cuesheet-edit-modal/useCuesheetEditModal';
@@ -15,52 +15,58 @@ function CuesheetTableMenu() {
const { addEntry, clone, deleteEntry, move } = useEntryActions();
const showModal = useCuesheetEditModal((state) => state.setEditableEntry);
if (!isOpen) {
return null;
}
return (
<Portal>
{isOpen && (
<Menu isOpen size='sm' onClose={closeMenu} isLazy variant='ontime-on-dark'>
<MenuButton
position='absolute'
left={position.x}
top={position.y}
pointerEvents='none'
aria-hidden
w={1}
h={1}
/>
<MenuList>
<MenuItem icon={<IoOptions />} onClick={() => showModal(entryId)}>
Edit ...
</MenuItem>
<MenuDivider />
<MenuItem
icon={<IoAdd />}
onClick={() => addEntry({ type: SupportedEntry.Event, parent: parentId }, { before: entryId })}
>
Add event above
</MenuItem>
<MenuItem
icon={<IoAdd />}
onClick={() => addEntry({ type: SupportedEntry.Event, parent: parentId }, { after: entryId })}
>
Add event below
</MenuItem>
<MenuItem icon={<IoDuplicateOutline />} onClick={() => clone(entryId)}>
Clone event
</MenuItem>
<MenuDivider />
<MenuItem isDisabled={entryIndex < 1} icon={<IoArrowUp />} onClick={() => move(entryId, 'up')}>
Move up
</MenuItem>
<MenuItem icon={<IoArrowDown />} onClick={() => move(entryId, 'down')}>
Move down
</MenuItem>
<MenuItem icon={<IoTrash />} onClick={() => deleteEntry([entryId])}>
Delete
</MenuItem>
</MenuList>
</Menu>
)}
</Portal>
<Menu
isOpen
onClose={closeMenu}
items={[
{ type: 'item', label: 'Edit...', onClick: () => showModal(entryId), icon: <IoOptions /> },
{ type: 'divider' },
{
type: 'item',
label: 'Add event above',
onClick: () => addEntry({ type: SupportedEntry.Event, parent: parentId }, { before: entryId }),
icon: <IoAdd />,
},
{
type: 'item',
label: 'Add event below',
onClick: () => addEntry({ type: SupportedEntry.Event, parent: parentId }, { after: entryId }),
icon: <IoAdd />,
},
{
type: 'item',
label: 'Clone event',
onClick: () => clone(entryId),
icon: <IoDuplicateOutline />,
},
{ type: 'divider' },
{
type: 'item',
label: 'Move up',
onClick: () => move(entryId, 'up'),
icon: <IoArrowUp />,
disabled: entryIndex < 1,
},
{
type: 'item',
label: 'Move down',
onClick: () => move(entryId, 'down'),
icon: <IoArrowDown />,
},
{ type: 'divider' },
{
type: 'item',
label: 'Delete',
onClick: () => deleteEntry([entryId]),
icon: <IoTrash />,
},
]}
position={position}
/>
);
}
@@ -1,4 +1,4 @@
import { EntryId } from 'ontime-types';
import { EntryId, SupportedEntry } from 'ontime-types';
import { create } from 'zustand';
type Anchor = { x: number; y: number };
@@ -6,6 +6,7 @@ type Anchor = { x: number; y: number };
type OpenMenu = {
isOpen: true;
entryId: EntryId;
entryType: SupportedEntry;
entryIndex: number;
parentId: EntryId | null;
};
@@ -13,23 +14,36 @@ type OpenMenu = {
type ClosedMenu = {
isOpen: false;
entryId: null;
entryType: null;
entryIndex: null;
parentId: null;
};
type CuesheetTableMenuStore = (OpenMenu | ClosedMenu) & {
position: Anchor;
openMenu: (position: Anchor, entryId: EntryId, entryIndex: number, parentId: EntryId | null) => void;
openMenu: (
position: Anchor,
entryId: EntryId,
entryType: SupportedEntry,
entryIndex: number,
parentId: EntryId | null,
) => void;
closeMenu: () => void;
};
export const useCuesheetTableMenu = create<CuesheetTableMenuStore>((set) => ({
isOpen: false,
entryId: null,
entryType: null,
entryIndex: null,
parentId: null,
position: { x: 0, y: 0 },
openMenu: (position: Anchor, entryId: EntryId, entryIndex: number, parentId: EntryId | null) =>
set({ isOpen: true, position, entryId, entryIndex, parentId }),
openMenu: (
position: Anchor,
entryId: EntryId,
entryType: SupportedEntry,
entryIndex: number,
parentId: EntryId | null,
) => set({ isOpen: true, position, entryId, entryType, entryIndex, parentId }),
closeMenu: () => set({ isOpen: false }),
}));