feat: add flag property

This commit is contained in:
Carlos Valente
2025-07-13 12:43:33 +02:00
parent e9dda817e5
commit 637454f73d
22 changed files with 98 additions and 23 deletions
@@ -5,6 +5,7 @@ export type NamedImportMap = typeof namedImportMap;
// Record of label and import name
const namedImportMap = {
Worksheet: 'event schedule',
Flag: 'flag',
Start: 'time start',
'Link start': 'link start',
End: 'time end',
@@ -42,6 +43,7 @@ export function convertToImportMap(namedImportMap: NamedImportMap): ImportMap {
return {
worksheet: namedImportMap.Worksheet,
flag: namedImportMap.Flag,
timeStart: namedImportMap.Start,
linkStart: namedImportMap['Link start'],
timeEnd: namedImportMap.End,
@@ -35,6 +35,7 @@ export default function PreviewRundown(props: PreviewRundownProps) {
<th>Type</th>
<th>Cue</th>
<th>Title</th>
<th>Flag</th>
<th>Time Start</th>
<th>Time End</th>
<th>Duration</th>
@@ -75,6 +76,7 @@ export default function PreviewRundown(props: PreviewRundownProps) {
const colour = entry.colour ? getAccessibleColour(entry.colour) : {};
const countToEnd = booleanToText(entry.countToEnd);
const skip = booleanToText(entry.skip);
const flag = booleanToText(entry.flag);
return (
<Fragment key={entry.id}>
@@ -87,6 +89,7 @@ export default function PreviewRundown(props: PreviewRundownProps) {
</td>
<td className={style.nowrap}>{entry.cue}</td>
<td>{entry.title}</td>
<td className={style.center}>{flag && <Tag>{flag}</Tag>}</td>
<td className={style.flex}>
<span className={entry.linkStart ? style.subdued : undefined}>{millisToString(entry.timeStart)}</span>
{entry.linkStart && <IoLink className={style.linkStartActive} />}
@@ -1,4 +1,5 @@
import { IoArrowDown, IoArrowUp, IoBan, IoFlag, IoTime } from 'react-icons/io5';
import { IoArrowDown, IoArrowUp, IoBan, IoTime } from 'react-icons/io5';
import { LuArrowDownToLine } from 'react-icons/lu';
import { TimerPhase, TimerType } from 'ontime-types';
import { Corner } from '../../../common/components/editor-utils/EditorUtils';
@@ -101,7 +102,7 @@ export default function TimerPreview() {
className={style.statusIcon}
data-active={countToEnd}
>
<IoFlag />
<LuArrowDownToLine />
</Tooltip>
</div>
</div>
@@ -177,6 +177,7 @@ export default function RundownEntry({
duration={data.duration}
timeStrategy={data.timeStrategy}
linkStart={data.linkStart}
flag={data.flag}
countToEnd={data.countToEnd}
endAction={data.endAction}
timerType={data.timerType}
@@ -72,6 +72,13 @@
row-gap: 1rem;
}
.splitThree {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
column-gap: 1rem;
row-gap: 1rem;
}
.tooltipIcon {
color: $blue-500;
display: inline-block;
@@ -59,10 +59,10 @@ export default function EventEditor({ event }: EventEditorProps) {
key={`${event.id}-titles`}
eventId={event.id}
cue={event.cue}
flag={event.flag}
title={event.title}
note={event.note}
colour={event.colour}
handleSubmit={handleSubmit}
/>
<div className={style.column}>
<Editor.Title>
@@ -7,7 +7,7 @@ interface EventEditorImageProps {
export default function EventEditorImage({ src }: EventEditorImageProps) {
return (
<div className={style.imageContainer}>
<img loading='lazy' src={src} />
{Boolean(src) && <img loading='lazy' src={src} />}
<div className={style.imageOverlay} />
</div>
);
@@ -4,7 +4,8 @@ import { sanitiseCue } from 'ontime-utils';
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
import SwatchSelect from '../../../../common/components/input/colour-input/SwatchSelect';
import Input from '../../../../common/components/input/input/Input';
import { type EventEditorUpdateFields } from '../EventEditor';
import Switch from '../../../../common/components/switch/Switch';
import { useEntryActions } from '../../../../common/hooks/useEntryAction';
import EventTextArea from './EventTextArea';
import EntryEditorTextInput from './EventTextInput';
@@ -14,22 +15,32 @@ import style from '../EntryEditor.module.scss';
interface EventEditorTitlesProps {
eventId: string;
cue: string;
flag: boolean;
title: string;
note: string;
colour: string;
handleSubmit: (field: EventEditorUpdateFields, value: string) => void;
}
export default memo(EventEditorTitles);
function EventEditorTitles({ eventId, cue, title, note, colour, handleSubmit }: EventEditorTitlesProps) {
function EventEditorTitles({ eventId, cue, flag, title, note, colour }: EventEditorTitlesProps) {
const { updateEntry } = useEntryActions();
const cueSubmitHandler = (_field: string, newValue: string) => {
handleSubmit('cue', sanitiseCue(newValue));
updateEntry({ id: eventId, cue: sanitiseCue(newValue) });
};
const flagSubmitHandler = (newValue: boolean) => {
updateEntry({ id: eventId, flag: newValue });
};
const textSubmitHandler = (field: string, newValue: string) => {
updateEntry({ id: eventId, [field]: newValue });
};
return (
<div className={style.column}>
<Editor.Title>Event Data</Editor.Title>
<div className={style.splitTwo}>
<div className={style.splitThree}>
<div>
<Editor.Label htmlFor='eventId'>Event ID (read only)</Editor.Label>
<Input id='eventId' data-testid='input-textfield' value={eventId} readOnly fluid />
@@ -41,13 +52,20 @@ function EventEditorTitles({ eventId, cue, title, note, colour, handleSubmit }:
submitHandler={cueSubmitHandler}
maxLength={10}
/>
<div>
<Editor.Label htmlFor='flag'>Flag</Editor.Label>
<Editor.Label className={style.switchLabel}>
<Switch id='flag' checked={flag} onCheckedChange={flagSubmitHandler} />
{flag ? 'On' : 'Off'}
</Editor.Label>
</div>
</div>
<div>
<Editor.Label>Colour</Editor.Label>
<SwatchSelect name='colour' value={colour} handleChange={handleSubmit} />
<SwatchSelect name='colour' value={colour} handleChange={textSubmitHandler} />
</div>
<EntryEditorTextInput field='title' label='Title' initialValue={title} submitHandler={handleSubmit} />
<EventTextArea field='note' label='Note' initialValue={note} submitHandler={handleSubmit} />
<EntryEditorTextInput field='title' label='Title' initialValue={title} submitHandler={textSubmitHandler} />
<EventTextArea field='note' label='Note' initialValue={note} submitHandler={textSubmitHandler} />
</div>
);
}
@@ -2,6 +2,7 @@ import { MouseEvent, useEffect, useLayoutEffect, useRef, useState } from 'react'
import {
IoAdd,
IoDuplicateOutline,
IoFlag,
IoFolder,
IoLink,
IoReorderTwo,
@@ -33,6 +34,7 @@ interface RundownEventProps {
duration: number;
timeStrategy: TimeStrategy;
linkStart: boolean;
flag: boolean;
countToEnd: boolean;
eventIndex: number;
endAction: EndAction;
@@ -74,6 +76,7 @@ export default function RundownEvent({
duration,
timeStrategy,
linkStart,
flag,
countToEnd,
eventIndex,
endAction,
@@ -118,7 +121,6 @@ export default function RundownEvent({
},
{
type: 'item',
label: 'Unlink from previous',
icon: IoUnlink,
onClick: () =>
@@ -135,7 +137,6 @@ export default function RundownEvent({
: [
{
type: 'item',
label: 'Toggle link to previous',
icon: IoLink,
onClick: () =>
@@ -144,18 +145,25 @@ export default function RundownEvent({
value: linkStart,
}),
},
{ type: 'divider' },
{
type: 'item',
label: flag ? 'Remove flag' : 'Add flag',
icon: IoFlag,
onClick: () =>
actionHandler('update', {
field: 'flag',
value: !flag,
}),
},
{ type: 'divider' },
{
type: 'item',
label: 'Add to swap',
icon: IoAdd,
onClick: () => setSelectedEventId(eventId),
},
{
type: 'item',
label: `Swap this event with ${selectedEventId ?? ''}`,
icon: IoSwapVertical,
onClick: () => {
@@ -3,13 +3,13 @@ import {
IoArrowDown,
IoArrowUp,
IoBan,
IoFlag,
IoFlash,
IoPlay,
IoPlayForward,
IoPlaySkipForward,
IoTime,
} from 'react-icons/io5';
import { LuArrowDownToLine } from 'react-icons/lu';
import { EndAction, Playback, TimerType, TimeStrategy } from 'ontime-types';
import Tooltip from '../../../common/components/tooltip/Tooltip';
@@ -143,7 +143,7 @@ function RundownEventInner({
<EndActionIcon action={endAction} className={style.statusIcon} />
</Tooltip>
<Tooltip text={`${countToEnd ? 'Count to End' : 'Count duration'}`} render={<span />}>
<IoFlag className={`${style.statusIcon} ${countToEnd ? style.active : style.disabled}`} />
<LuArrowDownToLine className={`${style.statusIcon} ${countToEnd ? style.active : style.disabled}`} />
</Tooltip>
<Tooltip text='Event has Triggers' render={<span />}>
<IoFlash className={`${style.statusIcon} ${hasTriggers ? style.active : style.disabled}`} />