feat: duplicate groups

This commit is contained in:
Carlos Valente
2025-05-19 20:01:03 +02:00
committed by arc-alex
parent 11e0215530
commit 2f26f20db5
20 changed files with 448 additions and 88 deletions
+2 -2
View File
@@ -37,7 +37,7 @@ import useFollowComponent from '../../common/hooks/useFollowComponent';
import { useRundownEditor } from '../../common/hooks/useSocket';
import { AppMode, useAppMode } from '../../common/stores/appModeStore';
import { useEntryCopy } from '../../common/stores/entryCopyStore';
import { cloneEvent } from '../../common/utils/eventsManager';
import { cloneEvent } from '../../common/utils/clone';
import BlockBlock from './block-block/BlockBlock';
import BlockEnd from './block-block/BlockEnd';
@@ -329,7 +329,7 @@ export default function Rundown({ data }: RundownProps) {
};
if (sortableData.length < 1) {
return <RundownEmpty handleAddNew={(type: SupportedEntry) => insertAtId({ type }, cursor)} />;
return <RundownEmpty handleAddNew={(type: SupportedEntry) => addEntry({ type })} />;
}
// 1. gather presentation options
@@ -12,7 +12,7 @@ import {
import { useEntryActions } from '../../common/hooks/useEntryAction';
import useMemoisedFn from '../../common/hooks/useMemoisedFn';
import { useEmitLog } from '../../common/stores/logger';
import { cloneEvent } from '../../common/utils/eventsManager';
import { cloneEvent } from '../../common/utils/clone';
import DelayBlock from './delay-block/DelayBlock';
import EventBlock from './event-block/EventBlock';
@@ -1,6 +1,14 @@
import { useRef } from 'react';
import { IoChevronDown, IoChevronUp, IoEllipsisHorizontal, IoReorderTwo } from 'react-icons/io5';
import { IconButton, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react';
import {
IoChevronDown,
IoChevronUp,
IoDuplicateOutline,
IoEllipsisHorizontal,
IoFolderOpenOutline,
IoReorderTwo,
IoTrash,
} from 'react-icons/io5';
import { IconButton, Menu, MenuButton, MenuItem, MenuList, Portal } from '@chakra-ui/react';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { EntryId, OntimeBlock } from 'ontime-types';
@@ -23,7 +31,7 @@ interface BlockBlockProps {
export default function BlockBlock(props: BlockBlockProps) {
const { data, hasCursor, collapsed, onCollapse } = props;
const handleRef = useRef<null | HTMLSpanElement>(null);
const { dissolveBlock } = useEntryActions();
const { clone, dissolveBlock, deleteEntry } = useEntryActions();
const {
attributes: dragAttributes,
@@ -52,6 +60,8 @@ export default function BlockBlock(props: BlockBlockProps) {
cursor: isOver ? (isValidDrop ? 'grabbing' : 'no-drop') : 'default',
};
const hasChildren = data.events.length > 0;
return (
<div
className={cx([style.block, hasCursor && style.hasCursor, !collapsed && style.expanded])}
@@ -83,12 +93,24 @@ export default function BlockBlock(props: BlockBlockProps) {
variant='ontime-ghosted'
size='sm'
/>
<MenuList>
<MenuItem onClick={() => dissolveBlock(data.id)}>Dissolve Block</MenuItem>
</MenuList>
<Portal>
<MenuList>
<MenuItem icon={<IoDuplicateOutline />} onClick={() => clone(data.id)}>
Clone Block
</MenuItem>
{hasChildren && (
<MenuItem icon={<IoFolderOpenOutline />} onClick={() => dissolveBlock(data.id)}>
Dissolve Block
</MenuItem>
)}
<MenuItem icon={<IoTrash />} onClick={() => deleteEntry([data.id])}>
Delete Block
</MenuItem>
</MenuList>
</Portal>
</Menu>
<IconButton
aria-label='Dissolve'
aria-label='Collapse'
onClick={() => onCollapse(!collapsed, data.id)}
color='#e2e2e2' // $gray-200
variant='ontime-ghosted'