chore: rename blocks to groups

This commit is contained in:
Carlos Valente
2025-08-09 06:47:13 +02:00
committed by Carlos Valente
parent 486d89ecf4
commit e5d2457717
83 changed files with 987 additions and 981 deletions
+65 -62
View File
@@ -16,8 +16,8 @@ import {
type EntryId,
type MaybeString,
type Rundown,
isOntimeBlock,
isOntimeEvent,
isOntimeGroup,
OntimeEntry,
Playback,
SupportedEntry,
@@ -25,9 +25,9 @@ import {
import {
getFirstNormal,
getLastNormal,
getNextBlockNormal,
getNextGroupNormal,
getNextNormal,
getPreviousBlockNormal,
getPreviousGroupNormal,
getPreviousNormal,
reorderArray,
} from 'ontime-utils';
@@ -41,8 +41,8 @@ import { AppMode, sessionKeys } from '../../ontimeConfig';
import QuickAddButtons from './entry-editor/quick-add-buttons/QuickAddButtons';
import QuickAddInline from './entry-editor/quick-add-cursor/QuickAddInline';
import RundownBlock from './rundown-block/RundownBlock';
import RundownBlockEnd from './rundown-block/RundownBlockEnd';
import RundownGroup from './rundown-group/RundownGroup';
import RundownGroupEnd from './rundown-group/RundownGroupEnd';
import { canDrop, makeRundownMetadata, makeSortableList } from './rundown.utils';
import RundownEmpty from './RundownEmpty';
import { useEventSelection } from './useEventSelection';
@@ -127,7 +127,7 @@ export default function Rundown({ data }: RundownProps) {
[addEntry],
);
const selectBlock = useCallback(
const selectGroup = useCallback(
(cursor: string | null, direction: 'up' | 'down') => {
if (order.length < 1) {
return;
@@ -137,7 +137,7 @@ export default function Rundown({ data }: RundownProps) {
// there is no cursor, we select the first or last depending on direction
const selected = direction === 'up' ? getLastNormal(entries, order) : getFirstNormal(entries, order);
if (isOntimeBlock(selected)) {
if (isOntimeGroup(selected)) {
setSelectedEvents({ id: selected.id, selectMode: 'click', index: direction === 'up' ? order.length : 0 });
return;
}
@@ -151,8 +151,8 @@ export default function Rundown({ data }: RundownProps) {
// otherwise we select the next or previous
const selected =
direction === 'up'
? getPreviousBlockNormal(entries, order, newCursor)
: getNextBlockNormal(entries, order, newCursor);
? getPreviousGroupNormal(entries, order, newCursor)
: getNextGroupNormal(entries, order, newCursor);
if (selected.entry !== null && selected.index !== null) {
setSelectedEvents({ id: selected.entry.id, selectMode: 'click', index: selected.index });
@@ -188,11 +188,11 @@ export default function Rundown({ data }: RundownProps) {
);
/**
* Checks whether a block is collapsed
* Checks whether a group is collapsed
*/
const getIsCollapsed = useCallback(
(blockId: EntryId): boolean => {
return Boolean(collapsedGroups.find((id) => id === blockId));
(groupId: EntryId): boolean => {
return Boolean(collapsedGroups.find((id) => id === groupId));
},
[collapsedGroups],
);
@@ -223,10 +223,10 @@ export default function Rundown({ data }: RundownProps) {
return;
}
const movedIntoBlockId = await move(cursor, direction);
// if we are moving into a block, we need to make sure it is expanded
if (movedIntoBlockId) {
handleCollapseGroup(false, movedIntoBlockId);
const movedIntoGroupId = await move(cursor, direction);
// if we are moving into a group, we need to make sure it is expanded
if (movedIntoGroupId) {
handleCollapseGroup(false, movedIntoGroupId);
}
},
[handleCollapseGroup, move],
@@ -237,8 +237,8 @@ export default function Rundown({ data }: RundownProps) {
['alt + ArrowDown', () => selectEntry(cursor, 'down'), { preventDefault: true, usePhysicalKeys: true }],
['alt + ArrowUp', () => selectEntry(cursor, 'up'), { preventDefault: true, usePhysicalKeys: true }],
['alt + shift + ArrowDown', () => selectBlock(cursor, 'down'), { preventDefault: true, usePhysicalKeys: true }],
['alt + shift + ArrowUp', () => selectBlock(cursor, 'up'), { preventDefault: true, usePhysicalKeys: true }],
['alt + shift + ArrowDown', () => selectGroup(cursor, 'down'), { preventDefault: true, usePhysicalKeys: true }],
['alt + shift + ArrowUp', () => selectGroup(cursor, 'up'), { preventDefault: true, usePhysicalKeys: true }],
['alt + mod + ArrowDown', () => moveEntry(cursor, 'down'), { preventDefault: true, usePhysicalKeys: true }],
['alt + mod + ArrowUp', () => moveEntry(cursor, 'up'), { preventDefault: true, usePhysicalKeys: true }],
@@ -260,12 +260,12 @@ export default function Rundown({ data }: RundownProps) {
[
'alt + G',
() => insertAtId({ type: SupportedEntry.Block }, cursor),
() => insertAtId({ type: SupportedEntry.Group }, cursor),
{ preventDefault: true, usePhysicalKeys: true },
],
[
'alt + shift + G',
() => insertAtId({ type: SupportedEntry.Block }, cursor, true),
() => insertAtId({ type: SupportedEntry.Group }, cursor, true),
{ preventDefault: true, usePhysicalKeys: true },
],
@@ -335,7 +335,10 @@ export default function Rundown({ data }: RundownProps) {
}
// prevent dropping a group inside another
if (active.data.current?.type === 'block' && !canDrop(over.data.current?.type, over.data.current?.parent)) {
if (
active.data.current?.type === SupportedEntry.Group &&
!canDrop(over.data.current?.type, over.data.current?.parent)
) {
return;
}
@@ -346,10 +349,10 @@ export default function Rundown({ data }: RundownProps) {
let order: 'before' | 'after' | 'insert' = fromIndex < toIndex ? 'after' : 'before';
/**
* We need to specially handle the end blocks
* Dragging before and end block will add the entry to the end of the block
* Dragging after an end block will add the event after the block itself
* Dragging to the top of a block either place before first entry or if no entries do insert
* We need to specially handle the end-group
* Dragging before a end-group will add the entry to the end of the group
* Dragging after a end-group will add the event after the group itself
* Dragging to the top of a group either place before first entry or if no entries do insert
*/
if (destinationId.startsWith('end-')) {
destinationId = destinationId.replace('end-', '');
@@ -358,11 +361,11 @@ export default function Rundown({ data }: RundownProps) {
order = 'insert';
}
} else {
const block = data.entries[destinationId];
if (isOntimeBlock(block) && order === 'after') {
if (block.entries.length === 0) order = 'insert';
const group = data.entries[destinationId];
if (isOntimeGroup(group) && order === 'after') {
if (group.entries.length === 0) order = 'insert';
else {
destinationId = block.entries[0];
destinationId = group.entries[0];
order = 'before';
}
}
@@ -380,31 +383,31 @@ export default function Rundown({ data }: RundownProps) {
};
/**
* When we drag a block, we force collapse it
* This avoids strange scenarios like dropping a block inside itself
* When we drag a group, we force collapse it
* This avoids strange scenarios like dropping a group inside itself
*/
const collapseDraggedBlocks = (event: DragStartEvent) => {
const isBlock = event.active.data.current?.type === 'block';
if (isBlock) {
const collapseDraggedGroups = (event: DragStartEvent) => {
const isGroup = event.active.data.current?.type === SupportedEntry.Group;
if (isGroup) {
handleCollapseGroup(true, event.active.id as EntryId);
}
};
/**
* When we drag over a block, we expand it if it is collapsed
* When we drag over a group, we expand it if it is collapsed
*/
const expandOverBlock = (event: DragOverEvent) => {
// if we are dragging a block, the drop operation is invalid so we dont expand
if (event.active.data.current?.type === 'block') {
const expandOverGroup = (event: DragOverEvent) => {
// if we are dragging a group, the drop operation is invalid so we dont expand
if (event.active.data.current?.type === 'group') {
return;
}
if (event.over?.data.current?.type !== 'block') {
if (event.over?.data.current?.type !== 'group') {
return;
}
const blockId = event.over?.id as EntryId;
const isCollapsed = getIsCollapsed(blockId);
const groupId = event.over?.id as EntryId;
const isCollapsed = getIsCollapsed(groupId);
if (isCollapsed) {
handleCollapseGroup(false, blockId);
handleCollapseGroup(false, groupId);
}
};
@@ -424,37 +427,37 @@ export default function Rundown({ data }: RundownProps) {
<div className={style.rundownContainer} ref={scrollRef} data-testid='rundown'>
<DndContext
onDragEnd={handleOnDragEnd}
onDragStart={collapseDraggedBlocks}
onDragOver={expandOverBlock}
onDragStart={collapseDraggedGroups}
onDragOver={expandOverGroup}
sensors={sensors}
collisionDetection={closestCenter}
>
<SortableContext items={sortableData} strategy={verticalListSortingStrategy}>
<div className={style.list}>
{isEditMode && <QuickAddButtons previousEventId={null} parentBlock={null} />}
{isEditMode && <QuickAddButtons previousEventId={null} parentGroup={null} />}
{sortableData.map((entryId, index) => {
// the entry might be a pseudo block-end which does not generate metadata and should not be processed
// the entry might be a pseudo end-group which does not generate metadata and should not be processed
if (entryId.startsWith('end-')) {
const parentId = entryId.split('end-')[1];
const isBlockCollapsed = getIsCollapsed(parentId);
const isGroupCollapsed = getIsCollapsed(parentId);
if (isBlockCollapsed) {
if (isGroupCollapsed) {
return null;
}
// if the previous element is selected, it will have its own QuickAddInline
// we use thisId instead of previousEntryId because the block end does not process
// we use thisId instead of previousEntryId because the end-group does not process
// and it does not cause the reassignment of the iteration id to the previous entry
return (
<Fragment key={entryId}>
{isEditMode && rundownMetadata.groupEntries === 0 && (
<QuickAddButtons
previousEventId={null}
parentBlock={parentId}
parentGroup={parentId}
backgroundColor={rundownMetadata.groupColour}
/>
)}
<RundownBlockEnd key={entryId} id={entryId} colour={rundownMetadata.groupColour} />
<RundownGroupEnd key={entryId} id={entryId} colour={rundownMetadata.groupColour} />
</Fragment>
);
}
@@ -469,7 +472,7 @@ export default function Rundown({ data }: RundownProps) {
// if the entry has a parent, and it is collapsed, render nothing
if (
entry.type !== SupportedEntry.Block &&
entry.type !== SupportedEntry.Group &&
rundownMetadata.groupId !== null &&
getIsCollapsed(rundownMetadata.groupId)
) {
@@ -480,12 +483,12 @@ export default function Rundown({ data }: RundownProps) {
const hasCursor = entry.id === cursor;
/**
* Outside a block, the value will be undefined
* Outside a group, the value will be undefined
* If the colour is empty string ''
* ie: we are inside a block, but there is no defined colour
* ie: we are inside a group, but there is no defined colour
* we default to $gray-500 #9d9d9d
*/
const blockColour = rundownMetadata.groupColour === '' ? '#9d9d9d' : rundownMetadata.groupColour;
const groupColour = rundownMetadata.groupColour === '' ? '#9d9d9d' : rundownMetadata.groupColour;
const isFirst = index === 0;
const isLast = entryId === order.at(-1);
@@ -510,10 +513,10 @@ export default function Rundown({ data }: RundownProps) {
* - if it is not the first entry (the buttons would be there)
*/}
{isEditMode && hasCursor && !isFirst && (
<QuickAddInline previousEventId={rundownMetadata.previousEntryId} parentBlock={parentIdForBefore} />
<QuickAddInline previousEventId={rundownMetadata.previousEntryId} parentGroup={parentIdForBefore} />
)}
{isOntimeBlock(entry) ? (
<RundownBlock
{isOntimeGroup(entry) ? (
<RundownGroup
data={entry}
hasCursor={hasCursor}
collapsed={getIsCollapsed(entry.id)}
@@ -523,7 +526,7 @@ export default function Rundown({ data }: RundownProps) {
<div
className={style.entryWrapper}
data-testid={`entry-${rundownMetadata.eventIndex}`}
style={blockColour ? { '--user-bg': blockColour } : {}}
style={groupColour ? { '--user-bg': groupColour } : {}}
>
{isOntimeEvent(entry) && (
<div className={style.entryIndex}>
@@ -556,16 +559,16 @@ export default function Rundown({ data }: RundownProps) {
* - edit mode only
* - if there is a cursor
* - if it is not the last entry (the buttons would be there)
* - if the entry is not the block header
* - if the entry is not the group header
*/}
{isEditMode && hasCursor && !isLast && (
<QuickAddInline previousEventId={entry.id} parentBlock={parentIdForAfter} />
<QuickAddInline previousEventId={entry.id} parentGroup={parentIdForAfter} />
)}
</Fragment>
);
})}
{isEditMode && (
<QuickAddButtons previousEventId={rundownMetadata.groupId ?? rundownMetadata.thisId} parentBlock={null} />
<QuickAddButtons previousEventId={rundownMetadata.groupId ?? rundownMetadata.thisId} parentGroup={null} />
)}
<div className={style.spacer} />
</div>