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
@@ -1,10 +1,10 @@
import { useEffect, useState } from 'react';
import { isOntimeBlock, isOntimeEvent, OntimeEntry } from 'ontime-types';
import { isOntimeEvent, isOntimeGroup, OntimeEntry } from 'ontime-types';
import useRundown from '../../../common/hooks-query/useRundown';
import BlockEditor from './BlockEditor';
import EventEditor from './EventEditor';
import GroupEditor from './GroupEditor';
import style from './EntryEditor.module.scss';
@@ -38,10 +38,10 @@ export default function CuesheetEntryEditor({ entryId }: CuesheetEntryEditorProp
);
}
if (isOntimeBlock(entry)) {
if (isOntimeGroup(entry)) {
return (
<div className={style.inModal} data-testid='editor-container'>
<BlockEditor block={entry} />
<GroupEditor group={entry} />
</div>
);
}
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
import { MaybeNumber, OntimeBlock } from 'ontime-types';
import { MaybeNumber, OntimeGroup } from 'ontime-types';
import { millisToString } from 'ontime-utils';
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
@@ -19,38 +19,38 @@ import TargetDurationInput from './composite/TargetDurationInput';
import style from './EntryEditor.module.scss';
// title + colour + custom field labels
export type BlockEditorUpdateTextFields = 'title' | 'colour' | string;
export type BlockEditorUpdateMaybeNumberFields = 'targetDuration';
export type GroupEditorUpdateTextFields = 'title' | 'colour' | string;
export type GroupEditorUpdateMaybeNumberFields = 'targetDuration';
interface BlockEditorProps {
block: OntimeBlock;
interface GroupEditorProps {
group: OntimeGroup;
}
export default function BlockEditor({ block }: BlockEditorProps) {
export default function GroupEditor({ group }: GroupEditorProps) {
const { data: customFields } = useCustomFields();
const { updateEntry } = useEntryActions();
const handleSubmit = useCallback(
(field: BlockEditorUpdateTextFields | BlockEditorUpdateMaybeNumberFields, value: string | MaybeNumber) => {
(field: GroupEditorUpdateTextFields | GroupEditorUpdateMaybeNumberFields, value: string | MaybeNumber) => {
// Handle custom fields
if (typeof field === 'string' && field.startsWith('custom-')) {
const fieldLabel = field.split('custom-')[1];
updateEntry({ id: block.id, custom: { [fieldLabel]: value as string } });
updateEntry({ id: group.id, custom: { [fieldLabel]: value as string } });
return;
}
if (field === 'targetDuration') {
return updateEntry({ id: block.id, targetDuration: value as MaybeNumber });
return updateEntry({ id: group.id, targetDuration: value as MaybeNumber });
}
// all other strings are text fields
return updateEntry({ id: block.id, [field]: value as string });
return updateEntry({ id: group.id, [field]: value as string });
},
[block.id, updateEntry],
[group.id, updateEntry],
);
const isEditor = window.location.pathname.includes('editor');
const planOffset = typeof block.targetDuration !== 'number' ? null : block.duration - block.targetDuration;
const planOffset = typeof group.targetDuration !== 'number' ? null : group.duration - group.targetDuration;
const planOffsetLabel = planOffset !== null ? getOffsetState(planOffset * -1) : null;
return (
@@ -64,19 +64,19 @@ export default function BlockEditor({ block }: BlockEditorProps) {
}
<Editor.Label>First event start</Editor.Label>
<TextLikeInput className={style.textLikeInput}>
{millisToString(block.timeStart, { fallback: timerPlaceholder })}
{millisToString(group.timeStart, { fallback: timerPlaceholder })}
</TextLikeInput>
</div>
<div>
<Editor.Label>Last event end</Editor.Label>
<TextLikeInput className={style.textLikeInput}>
{millisToString(block.timeEnd, { fallback: timerPlaceholder })}
{millisToString(group.timeEnd, { fallback: timerPlaceholder })}
</TextLikeInput>
</div>
<div>
<Editor.Label htmlFor='duration'>Scheduled duration</Editor.Label>
<TextLikeInput className={style.textLikeInput}>
{millisToString(block.duration, { fallback: enDash })}
{millisToString(group.duration, { fallback: enDash })}
</TextLikeInput>
</div>
</div>
@@ -93,21 +93,21 @@ export default function BlockEditor({ block }: BlockEditorProps) {
</TextLikeInput>
</div>
<TargetDurationInput
duration={block.duration}
targetDuration={block.targetDuration}
duration={group.duration}
targetDuration={group.targetDuration}
submitHandler={handleSubmit}
/>
</div>
</div>
<div className={style.column}>
<Editor.Title>Block data</Editor.Title>
<Editor.Title>Group data</Editor.Title>
<div>
<Editor.Label>Colour</Editor.Label>
<SwatchSelect name='colour' value={block.colour} handleChange={handleSubmit} />
<SwatchSelect name='colour' value={group.colour} handleChange={handleSubmit} />
</div>
<EntryEditorTextInput field='title' label='Title' initialValue={block.title} submitHandler={handleSubmit} />
<EventTextArea field='note' label='Note' initialValue={block.note} submitHandler={handleSubmit} />
<EntryEditorTextInput field='title' label='Title' initialValue={group.title} submitHandler={handleSubmit} />
<EventTextArea field='note' label='Note' initialValue={group.note} submitHandler={handleSubmit} />
</div>
<div className={style.column}>
@@ -115,7 +115,7 @@ export default function BlockEditor({ block }: BlockEditorProps) {
Custom Fields
{isEditor && <AppLink search='settings=manage__custom'>Manage Custom Fields</AppLink>}
</Editor.Title>
<EntryEditorCustomFields fields={customFields} handleSubmit={handleSubmit} entry={block} />
<EntryEditorCustomFields fields={customFields} handleSubmit={handleSubmit} entry={group} />
</div>
</div>
);
@@ -1,11 +1,11 @@
import { useEffect, useState } from 'react';
import {
isOntimeBlock,
isOntimeDelay,
isOntimeEvent,
isOntimeGroup,
isOntimeMilestone,
OntimeBlock,
OntimeEvent,
OntimeGroup,
OntimeMilestone,
} from 'ontime-types';
@@ -13,9 +13,9 @@ import useRundown from '../../../common/hooks-query/useRundown';
import { useEventSelection } from '../useEventSelection';
import EventEditorFooter from './composite/EventEditorFooter';
import BlockEditor from './BlockEditor';
import EventEditor from './EventEditor';
import EventEditorEmpty from './EventEditorEmpty';
import GroupEditor from './GroupEditor';
import MilestoneEditor from './MilestoneEditor';
import style from './EntryEditor.module.scss';
@@ -24,7 +24,7 @@ export default function RundownEntryEditor() {
const selectedEvents = useEventSelection((state) => state.selectedEvents);
const { data } = useRundown();
const [entry, setEntry] = useState<OntimeEvent | OntimeBlock | OntimeMilestone | null>(null);
const [entry, setEntry] = useState<OntimeEvent | OntimeGroup | OntimeMilestone | null>(null);
useEffect(() => {
if (data.order.length === 0) {
@@ -67,10 +67,10 @@ export default function RundownEntryEditor() {
);
}
if (isOntimeBlock(entry)) {
if (isOntimeGroup(entry)) {
return (
<div className={style.entryEditor} data-testid='editor-container'>
<BlockEditor block={entry} />
<GroupEditor group={entry} />
</div>
);
}
@@ -1,5 +1,5 @@
import { CSSProperties, Fragment } from 'react';
import { CustomFields, OntimeBlock, OntimeEvent, OntimeMilestone } from 'ontime-types';
import { CustomFields, OntimeEvent, OntimeGroup, OntimeMilestone } from 'ontime-types';
import { getAccessibleColour } from '../../../../common/utils/styleUtils';
import { EventEditorUpdateFields } from '../EventEditor';
@@ -12,7 +12,7 @@ import style from '../EntryEditor.module.scss';
interface EntryEditorCustomFieldsProps {
fields: CustomFields;
entry: OntimeEvent | OntimeBlock | OntimeMilestone;
entry: OntimeEvent | OntimeGroup | OntimeMilestone;
handleSubmit: (field: EventEditorUpdateFields, value: string) => void;
}
@@ -3,11 +3,11 @@ import { useCallback, useRef } from 'react';
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
import Input, { type InputProps } from '../../../../common/components/input/input/Input';
import useReactiveTextInput from '../../../../common/components/input/text-input/useReactiveTextInput';
import { BlockEditorUpdateTextFields } from '../BlockEditor';
import { EventEditorUpdateFields } from '../EventEditor';
import { GroupEditorUpdateTextFields } from '../GroupEditor';
interface EntryEditorTextInputProps extends InputProps {
field: EventEditorUpdateFields | BlockEditorUpdateTextFields;
field: EventEditorUpdateFields | GroupEditorUpdateTextFields;
label: string;
initialValue: string;
placeholder?: string;
@@ -17,27 +17,27 @@ interface TargetDurationInputProps {
}
export default function TargetDurationInput({ duration, targetDuration, submitHandler }: TargetDurationInputProps) {
const isBlocked = targetDuration !== null;
const isLocked = targetDuration !== null;
return (
<div>
<Editor.Label htmlFor='targetDuration'>Target duration</Editor.Label>
<TimeInputGroup hasDelay={isBlocked && targetDuration !== duration}>
<TimeInputGroup hasDelay={isLocked && targetDuration !== duration}>
<NullableTimeInput
name='targetDuration'
time={targetDuration}
submitHandler={submitHandler}
emptyDisplay={enDash}
className={isBlocked ? '' : style.inactive}
className={isLocked ? '' : style.inactive}
/>
<Tooltip
text='Lock to target duration'
className={cx([style.timeAction, isBlocked && style.active])}
onClick={() => submitHandler('targetDuration', isBlocked ? null : duration)}
className={cx([style.timeAction, isLocked && style.active])}
onClick={() => submitHandler('targetDuration', isLocked ? null : duration)}
data-testid='lock__duration'
render={<IconButton variant='subtle-white' className={isBlocked ? style.active : style.inactive} />}
render={<IconButton variant='subtle-white' className={isLocked ? style.active : style.inactive} />}
>
{isBlocked ? <IoLockClosed /> : <IoLockOpenOutline />}
{isLocked ? <IoLockClosed /> : <IoLockOpenOutline />}
</Tooltip>
</TimeInputGroup>
</div>
@@ -11,19 +11,19 @@ import style from './QuickAddButtons.module.scss';
interface QuickAddButtonsProps {
previousEventId: MaybeString;
parentBlock: MaybeString;
parentGroup: MaybeString;
backgroundColor?: string;
}
export default memo(QuickAddButtons);
function QuickAddButtons({ previousEventId, parentBlock, backgroundColor }: QuickAddButtonsProps) {
function QuickAddButtons({ previousEventId, parentGroup, backgroundColor }: QuickAddButtonsProps) {
const { addEntry } = useEntryActions();
const addEvent = () => {
addEntry(
{
type: SupportedEntry.Event,
parent: parentBlock,
parent: parentGroup,
},
{
after: previousEventId,
@@ -34,7 +34,7 @@ function QuickAddButtons({ previousEventId, parentBlock, backgroundColor }: Quic
const addDelay = () => {
addEntry(
{ type: SupportedEntry.Delay, parent: parentBlock },
{ type: SupportedEntry.Delay, parent: parentGroup },
{
lastEventId: previousEventId,
after: previousEventId,
@@ -44,7 +44,7 @@ function QuickAddButtons({ previousEventId, parentBlock, backgroundColor }: Quic
const addMilestone = () => {
addEntry(
{ type: SupportedEntry.Milestone, parent: parentBlock },
{ type: SupportedEntry.Milestone, parent: parentGroup },
{
lastEventId: previousEventId,
after: previousEventId,
@@ -52,12 +52,12 @@ function QuickAddButtons({ previousEventId, parentBlock, backgroundColor }: Quic
);
};
const addBlock = () => {
if (parentBlock !== null) {
const addGroup = () => {
if (parentGroup !== null) {
return;
}
addEntry(
{ type: SupportedEntry.Block },
{ type: SupportedEntry.Group },
{
lastEventId: previousEventId,
after: previousEventId,
@@ -67,15 +67,15 @@ function QuickAddButtons({ previousEventId, parentBlock, backgroundColor }: Quic
/**
* 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 = backgroundColor === '' ? '#9d9d9d' : backgroundColor;
const groupColour = backgroundColor === '' ? '#9d9d9d' : backgroundColor;
return (
<Toolbar.Root
className={cx([style.quickAdd, Boolean(parentBlock) && style.indent])}
style={blockColour ? { '--user-bg': blockColour } : {}}
className={cx([style.quickAdd, Boolean(parentGroup) && style.indent])}
style={groupColour ? { '--user-bg': groupColour } : {}}
data-testid='quick-add-buttons'
>
<Toolbar.Button render={<Button size='small' />} onClick={addEvent}>
@@ -93,8 +93,8 @@ function QuickAddButtons({ previousEventId, parentBlock, backgroundColor }: Quic
Milestone
</Toolbar.Button>
{parentBlock === null && (
<Toolbar.Button render={<Button size='small' />} onClick={addBlock}>
{parentGroup === null && (
<Toolbar.Button render={<Button size='small' />} onClick={addGroup}>
<IoAdd />
Group
</Toolbar.Button>
@@ -10,18 +10,18 @@ import style from './QuickAddInline.module.scss';
interface QuickAddInlineProps {
previousEventId: MaybeString;
parentBlock: MaybeString;
parentGroup: MaybeString;
}
export default memo(QuickAddInline);
function QuickAddInline({ previousEventId, parentBlock }: QuickAddInlineProps) {
function QuickAddInline({ previousEventId, parentGroup }: QuickAddInlineProps) {
const { addEntry } = useEntryActions();
const addEvent = () => {
addEntry(
{
type: SupportedEntry.Event,
parent: parentBlock,
parent: parentGroup,
},
{
after: previousEventId,
@@ -32,7 +32,7 @@ function QuickAddInline({ previousEventId, parentBlock }: QuickAddInlineProps) {
const addDelay = () => {
addEntry(
{ type: SupportedEntry.Delay, parent: parentBlock },
{ type: SupportedEntry.Delay, parent: parentGroup },
{
lastEventId: previousEventId,
after: previousEventId,
@@ -42,7 +42,7 @@ function QuickAddInline({ previousEventId, parentBlock }: QuickAddInlineProps) {
const addMilestone = () => {
addEntry(
{ type: SupportedEntry.Milestone, parent: parentBlock },
{ type: SupportedEntry.Milestone, parent: parentGroup },
{
lastEventId: previousEventId,
after: previousEventId,
@@ -50,12 +50,12 @@ function QuickAddInline({ previousEventId, parentBlock }: QuickAddInlineProps) {
);
};
const addBlock = () => {
if (parentBlock !== null) {
const addGroup = () => {
if (parentGroup !== null) {
return;
}
addEntry(
{ type: SupportedEntry.Block },
{ type: SupportedEntry.Group },
{
lastEventId: previousEventId,
after: previousEventId,
@@ -70,7 +70,7 @@ function QuickAddInline({ previousEventId, parentBlock }: QuickAddInlineProps) {
{ type: 'item', icon: IoAdd, label: 'Add Event', onClick: addEvent },
{ type: 'item', icon: IoAdd, label: 'Add Delay', onClick: addDelay },
{ type: 'item', icon: IoAdd, label: 'Add Milestone', onClick: addMilestone },
{ type: 'item', icon: IoAdd, label: 'Add Group', onClick: addBlock, disabled: parentBlock !== null },
{ type: 'item', icon: IoAdd, label: 'Add Group', onClick: addGroup, disabled: parentGroup !== null },
]}
render={<IconButton size='small' variant='primary' className={style.addButton} />}
>