mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-11 18:33:53 +00:00
chore: improve convention entry <> event
This commit is contained in:
@@ -2,7 +2,7 @@ import { useRef, useState } from 'react';
|
||||
import { Button, Textarea } from '@chakra-ui/react';
|
||||
import { OntimeEvent } from 'ontime-types';
|
||||
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||
import type { EditEvent } from '../Operator';
|
||||
|
||||
import style from './EditModal.module.scss';
|
||||
@@ -15,7 +15,7 @@ interface EditModalProps {
|
||||
export default function EditModal(props: EditModalProps) {
|
||||
const { event, onClose } = props;
|
||||
|
||||
const { updateEvent } = useEventAction();
|
||||
const { updateEntry } = useEntryActions();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const inputRef = useRef<HTMLTextAreaElement[]>(new Array<HTMLTextAreaElement>());
|
||||
|
||||
@@ -36,7 +36,7 @@ export default function EditModal(props: EditModalProps) {
|
||||
});
|
||||
|
||||
if (patchObject.custom) {
|
||||
await updateEvent(patchObject);
|
||||
await updateEntry(patchObject);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
reorderArray,
|
||||
} from 'ontime-utils';
|
||||
|
||||
import { type EventOptions, useEventAction } from '../../common/hooks/useEventAction';
|
||||
import { type EventOptions, useEntryActions } from '../../common/hooks/useEntryAction';
|
||||
import useFollowComponent from '../../common/hooks/useFollowComponent';
|
||||
import { useRundownEditor } from '../../common/hooks/useSocket';
|
||||
import { AppMode, useAppMode } from '../../common/stores/appModeStore';
|
||||
@@ -48,7 +48,7 @@ export default function Rundown({ data }: RundownProps) {
|
||||
const [statefulEntries, setStatefulEntries] = useState<EntryId[]>(order);
|
||||
|
||||
const featureData = useRundownEditor();
|
||||
const { addEvent, reorderEvent, deleteEvent } = useEventAction();
|
||||
const { addEntry, reorderEntry, deleteEntry } = useEntryActions();
|
||||
|
||||
const { entryCopyId, setEntryCopyId } = useEntryCopy();
|
||||
|
||||
@@ -67,12 +67,12 @@ export default function Rundown({ data }: RundownProps) {
|
||||
(cursor: string | null) => {
|
||||
if (!cursor) return;
|
||||
const { entry, index } = getPreviousNormal(entries, order, cursor);
|
||||
deleteEvent([cursor]);
|
||||
deleteEntry([cursor]);
|
||||
if (entry && index !== null) {
|
||||
setSelectedEvents({ id: entry.id, selectMode: 'click', index });
|
||||
}
|
||||
},
|
||||
[entries, order, deleteEvent, setSelectedEvents],
|
||||
[entries, order, deleteEntry, setSelectedEvents],
|
||||
);
|
||||
|
||||
const insertCopyAtId = useCallback(
|
||||
@@ -86,10 +86,10 @@ export default function Rundown({ data }: RundownProps) {
|
||||
if (cloneEntry?.type === SupportedEvent.Event) {
|
||||
//if we don't have a cursor add the new event on top
|
||||
const newEvent = cloneEvent(cloneEntry);
|
||||
addEvent(newEvent, { after: adjustedCursor ?? undefined });
|
||||
addEntry(newEvent, { after: adjustedCursor ?? undefined });
|
||||
}
|
||||
},
|
||||
[addEvent, order, entries],
|
||||
[addEntry, order, entries],
|
||||
);
|
||||
|
||||
const insertAtId = useCallback(
|
||||
@@ -109,12 +109,12 @@ export default function Rundown({ data }: RundownProps) {
|
||||
if (!above && id) {
|
||||
options.lastEventId = id;
|
||||
}
|
||||
addEvent(newEvent, options);
|
||||
addEntry(newEvent, options);
|
||||
} else {
|
||||
addEvent({ type }, options);
|
||||
addEntry({ type }, options);
|
||||
}
|
||||
},
|
||||
[addEvent],
|
||||
[addEntry],
|
||||
);
|
||||
|
||||
const selectBlock = useCallback(
|
||||
@@ -187,10 +187,10 @@ export default function Rundown({ data }: RundownProps) {
|
||||
|
||||
if (index !== null) {
|
||||
const offsetIndex = direction === 'up' ? index + 1 : index - 1;
|
||||
reorderEvent(cursor, offsetIndex, index);
|
||||
reorderEntry(cursor, offsetIndex, index);
|
||||
}
|
||||
},
|
||||
[order, reorderEvent, entries],
|
||||
[order, reorderEntry, entries],
|
||||
);
|
||||
|
||||
// shortcuts
|
||||
@@ -254,7 +254,7 @@ export default function Rundown({ data }: RundownProps) {
|
||||
setStatefulEntries((currentEntries) => {
|
||||
return reorderArray(currentEntries, fromIndex, toIndex);
|
||||
});
|
||||
reorderEvent(String(active.id), fromIndex, toIndex);
|
||||
reorderEntry(String(active.id), fromIndex, toIndex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
SupportedEvent,
|
||||
} from 'ontime-types';
|
||||
|
||||
import { useEventAction } from '../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../common/hooks/useEntryAction';
|
||||
import useMemoisedFn from '../../common/hooks/useMemoisedFn';
|
||||
import { useEmitLog } from '../../common/stores/logger';
|
||||
import { cloneEvent } from '../../common/utils/eventsManager';
|
||||
@@ -66,7 +66,7 @@ export default function RundownEntry(props: RundownEntryProps) {
|
||||
isLinkedToLoaded,
|
||||
} = props;
|
||||
const { emitError } = useEmitLog();
|
||||
const { addEvent, updateEvent, batchUpdateEvents, deleteEvent, swapEvents } = useEventAction();
|
||||
const { addEntry, updateEntry, batchUpdateEvents, deleteEntry, swapEvents } = useEntryActions();
|
||||
const { selectedEvents, unselect, clearSelectedEvents } = useEventSelection();
|
||||
|
||||
const removeOpenEvent = useCallback(() => {
|
||||
@@ -91,26 +91,26 @@ export default function RundownEntry(props: RundownEntryProps) {
|
||||
after: data.id,
|
||||
lastEventId: previousEventId,
|
||||
};
|
||||
return addEvent(newEvent, options);
|
||||
return addEntry(newEvent, options);
|
||||
}
|
||||
case 'event-before': {
|
||||
const newEvent = { type: SupportedEvent.Event };
|
||||
const options = {
|
||||
after: previousEntryId,
|
||||
};
|
||||
return addEvent(newEvent, options);
|
||||
return addEntry(newEvent, options);
|
||||
}
|
||||
case 'delay': {
|
||||
return addEvent({ type: SupportedEvent.Delay }, { after: data.id });
|
||||
return addEntry({ type: SupportedEvent.Delay }, { after: data.id });
|
||||
}
|
||||
case 'delay-before': {
|
||||
return addEvent({ type: SupportedEvent.Delay }, { after: previousEntryId });
|
||||
return addEntry({ type: SupportedEvent.Delay }, { after: previousEntryId });
|
||||
}
|
||||
case 'block': {
|
||||
return addEvent({ type: SupportedEvent.Block }, { after: data.id });
|
||||
return addEntry({ type: SupportedEvent.Block }, { after: data.id });
|
||||
}
|
||||
case 'block-before': {
|
||||
return addEvent({ type: SupportedEvent.Block }, { after: previousEntryId });
|
||||
return addEntry({ type: SupportedEvent.Block }, { after: previousEntryId });
|
||||
}
|
||||
case 'swap': {
|
||||
const { value } = payload as FieldValue;
|
||||
@@ -119,14 +119,14 @@ export default function RundownEntry(props: RundownEntryProps) {
|
||||
case 'delete': {
|
||||
if (selectedEvents.size > 1) {
|
||||
clearMultiSelection();
|
||||
return deleteEvent(Array.from(selectedEvents));
|
||||
return deleteEntry(Array.from(selectedEvents));
|
||||
}
|
||||
removeOpenEvent();
|
||||
return deleteEvent([data.id]);
|
||||
return deleteEntry([data.id]);
|
||||
}
|
||||
case 'clone': {
|
||||
const newEvent = cloneEvent(data as OntimeEvent);
|
||||
addEvent(newEvent, { after: data.id });
|
||||
addEntry(newEvent, { after: data.id });
|
||||
break;
|
||||
}
|
||||
case 'update': {
|
||||
@@ -147,7 +147,7 @@ export default function RundownEntry(props: RundownEntryProps) {
|
||||
if (field in data) {
|
||||
// @ts-expect-error -- not sure how to type this
|
||||
newData[field] = value;
|
||||
return updateEvent(newData);
|
||||
return updateEntry(newData);
|
||||
}
|
||||
|
||||
return emitError(`Unknown field: ${field}`);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useCallback, useRef } from 'react';
|
||||
import { Input } from '@chakra-ui/react';
|
||||
|
||||
import useReactiveTextInput from '../../../common/components/input/text-input/useReactiveTextInput';
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||
import { cx } from '../../../common/utils/styleUtils';
|
||||
|
||||
import style from './TitleEditor.module.scss';
|
||||
@@ -16,7 +16,7 @@ interface TitleEditorProps {
|
||||
|
||||
export default function EditableBlockTitle(props: TitleEditorProps) {
|
||||
const { title, eventId, placeholder, className } = props;
|
||||
const { updateEvent } = useEventAction();
|
||||
const { updateEntry } = useEntryActions();
|
||||
const ref = useRef<HTMLInputElement | null>(null);
|
||||
const submitCallback = useCallback(
|
||||
(text: string) => {
|
||||
@@ -25,9 +25,9 @@ export default function EditableBlockTitle(props: TitleEditorProps) {
|
||||
}
|
||||
|
||||
const cleanVal = text.trim();
|
||||
updateEvent({ id: eventId, title: cleanVal });
|
||||
updateEntry({ id: eventId, title: cleanVal });
|
||||
},
|
||||
[title, updateEvent, eventId],
|
||||
[title, updateEntry, eventId],
|
||||
);
|
||||
|
||||
const { value, onChange, onBlur, onKeyDown } = useReactiveTextInput(title, submitCallback, ref, {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { CSS } from '@dnd-kit/utilities';
|
||||
import { OntimeDelay } from 'ontime-types';
|
||||
|
||||
import DelayInput from '../../../common/components/input/delay-input/DelayInput';
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||
import { cx } from '../../../common/utils/styleUtils';
|
||||
|
||||
import style from './DelayBlock.module.scss';
|
||||
@@ -18,7 +18,7 @@ interface DelayBlockProps {
|
||||
|
||||
export default function DelayBlock(props: DelayBlockProps) {
|
||||
const { data, hasCursor } = props;
|
||||
const { applyDelay, deleteEvent } = useEventAction();
|
||||
const { applyDelay, deleteEntry } = useEntryActions();
|
||||
const handleRef = useRef<null | HTMLSpanElement>(null);
|
||||
|
||||
const {
|
||||
@@ -48,7 +48,7 @@ export default function DelayBlock(props: DelayBlockProps) {
|
||||
};
|
||||
|
||||
const cancelDelayHandler = () => {
|
||||
deleteEvent([data.id]);
|
||||
deleteEntry([data.id]);
|
||||
};
|
||||
|
||||
const blockClasses = cx([style.delay, hasCursor ? style.hasCursor : null]);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { memo, MouseEvent } from 'react';
|
||||
import { IoPause, IoPlay, IoReload, IoRemoveCircle, IoRemoveCircleOutline } from 'react-icons/io5';
|
||||
|
||||
import TooltipActionBtn from '../../../../common/components/buttons/TooltipActionBtn';
|
||||
import { useEventAction } from '../../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../../common/hooks/useEntryAction';
|
||||
import { setEventPlayback } from '../../../../common/hooks/useSocket';
|
||||
import { tooltipDelayMid } from '../../../../ontimeConfig';
|
||||
|
||||
@@ -34,11 +34,11 @@ interface EventBlockPlaybackProps {
|
||||
|
||||
const EventBlockPlayback = (props: EventBlockPlaybackProps) => {
|
||||
const { eventId, skip, isPlaying, isPaused, loaded, disablePlayback } = props;
|
||||
const { updateEvent } = useEventAction();
|
||||
const { updateEntry } = useEntryActions();
|
||||
|
||||
const toggleSkip = (event: MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
updateEvent({ id: eventId, skip: !skip });
|
||||
updateEntry({ id: eventId, skip: !skip });
|
||||
};
|
||||
|
||||
const actionHandler = (event: MouseEvent) => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
|
||||
import { CustomFieldLabel, OntimeEvent } from 'ontime-types';
|
||||
|
||||
import AppLink from '../../../common/components/link/app-link/AppLink';
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||
import useCustomFields from '../../../common/hooks-query/useCustomFields';
|
||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
||||
|
||||
@@ -23,7 +23,7 @@ interface EventEditorProps {
|
||||
export default function EventEditor(props: EventEditorProps) {
|
||||
const { event } = props;
|
||||
const { data: customFields } = useCustomFields();
|
||||
const { updateEvent } = useEventAction();
|
||||
const { updateEntry } = useEntryActions();
|
||||
|
||||
const isEditor = window.location.pathname.includes('editor');
|
||||
|
||||
@@ -31,12 +31,12 @@ export default function EventEditor(props: EventEditorProps) {
|
||||
(field: EditorUpdateFields, value: string) => {
|
||||
if (field.startsWith('custom-')) {
|
||||
const fieldLabel = field.split('custom-')[1];
|
||||
updateEvent({ id: event?.id, custom: { [fieldLabel]: value } });
|
||||
updateEntry({ id: event?.id, custom: { [fieldLabel]: value } });
|
||||
} else {
|
||||
updateEvent({ id: event?.id, [field]: value });
|
||||
updateEntry({ id: event?.id, [field]: value });
|
||||
}
|
||||
},
|
||||
[event?.id, updateEvent],
|
||||
[event?.id, updateEntry],
|
||||
);
|
||||
|
||||
if (!event) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { EndAction, TimerType, TimeStrategy } from 'ontime-types';
|
||||
import { millisToString, parseUserTime } from 'ontime-utils';
|
||||
|
||||
import TimeInput from '../../../../common/components/input/time-input/TimeInput';
|
||||
import { useEventAction } from '../../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../../common/hooks/useEntryAction';
|
||||
import { millisToDelayString } from '../../../../common/utils/dateConfig';
|
||||
import * as Editor from '../../../editors/editor-utils/EditorUtils';
|
||||
import TimeInputFlow from '../../time-input-flow/TimeInputFlow';
|
||||
@@ -46,27 +46,27 @@ function EventEditorTimes(props: EventEditorTimesProps) {
|
||||
timeWarning,
|
||||
timeDanger,
|
||||
} = props;
|
||||
const { updateEvent } = useEventAction();
|
||||
const { updateEntry } = useEntryActions();
|
||||
|
||||
const handleSubmit = (field: HandledActions, value: string | boolean) => {
|
||||
if (field === 'isPublic') {
|
||||
updateEvent({ id: eventId, isPublic: !(value as boolean) });
|
||||
updateEntry({ id: eventId, isPublic: !(value as boolean) });
|
||||
return;
|
||||
}
|
||||
|
||||
if (field === 'countToEnd') {
|
||||
updateEvent({ id: eventId, countToEnd: !(value as boolean) });
|
||||
updateEntry({ id: eventId, countToEnd: !(value as boolean) });
|
||||
return;
|
||||
}
|
||||
|
||||
if (field === 'timeWarning' || field === 'timeDanger') {
|
||||
const newTime = parseUserTime(value as string);
|
||||
updateEvent({ id: eventId, [field]: newTime });
|
||||
updateEntry({ id: eventId, [field]: newTime });
|
||||
return;
|
||||
}
|
||||
|
||||
if (field === 'timerType' || field === 'endAction') {
|
||||
updateEvent({ id: eventId, [field]: value });
|
||||
updateEntry({ id: eventId, [field]: value });
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IoAdd } from 'react-icons/io5';
|
||||
import { Button } from '@chakra-ui/react';
|
||||
import { MaybeString, SupportedEvent } from 'ontime-types';
|
||||
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||
import { useEmitLog } from '../../../common/stores/logger';
|
||||
|
||||
import style from './QuickAddBlock.module.scss';
|
||||
@@ -17,7 +17,7 @@ export default memo(QuickAddBlock);
|
||||
|
||||
function QuickAddBlock(props: QuickAddBlockProps) {
|
||||
const { previousEventId, showBlocks } = props;
|
||||
const { addEvent } = useEventAction();
|
||||
const { addEntry } = useEntryActions();
|
||||
const { emitError } = useEmitLog();
|
||||
|
||||
const doLinkPrevious = useRef<HTMLInputElement | null>(null);
|
||||
@@ -37,7 +37,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
||||
lastEventId: previousEventId,
|
||||
linkPrevious,
|
||||
};
|
||||
addEvent(newEvent, options);
|
||||
addEntry(newEvent, options);
|
||||
break;
|
||||
}
|
||||
case 'delay': {
|
||||
@@ -45,7 +45,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
||||
lastEventId: previousEventId,
|
||||
after: previousEventId,
|
||||
};
|
||||
addEvent({ type: SupportedEvent.Delay }, options);
|
||||
addEntry({ type: SupportedEvent.Delay }, options);
|
||||
break;
|
||||
}
|
||||
case 'block': {
|
||||
@@ -53,7 +53,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
||||
lastEventId: previousEventId,
|
||||
after: previousEventId,
|
||||
};
|
||||
addEvent({ type: SupportedEvent.Block }, options);
|
||||
addEntry({ type: SupportedEvent.Block }, options);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -62,7 +62,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
||||
}
|
||||
}
|
||||
},
|
||||
[previousEventId, addEvent, emitError],
|
||||
[previousEventId, addEntry, emitError],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -11,23 +11,23 @@ import {
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||
import { useAppMode } from '../../../common/stores/appModeStore';
|
||||
import { useEventSelection } from '../useEventSelection';
|
||||
|
||||
export default function RundownMenu() {
|
||||
const clearSelectedEvents = useEventSelection((state) => state.clearSelectedEvents);
|
||||
const appMode = useAppMode((state) => state.mode);
|
||||
const { deleteAllEvents } = useEventAction();
|
||||
const { deleteAllEntries } = useEntryActions();
|
||||
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const cancelRef = useRef<HTMLButtonElement | null>(null);
|
||||
|
||||
const deleteAll = useCallback(() => {
|
||||
deleteAllEvents();
|
||||
deleteAllEntries();
|
||||
clearSelectedEvents();
|
||||
onClose();
|
||||
}, [clearSelectedEvents, deleteAllEvents, onClose]);
|
||||
}, [clearSelectedEvents, deleteAllEntries, onClose]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TimeField, TimeStrategy } from 'ontime-types';
|
||||
import { dayInMs } from 'ontime-utils';
|
||||
|
||||
import TimeInputWithButton from '../../../common/components/input/time-input/TimeInputWithButton';
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||
import { cx } from '../../../common/utils/styleUtils';
|
||||
import { tooltipDelayFast, tooltipDelayMid } from '../../../ontimeConfig';
|
||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
||||
@@ -26,7 +26,7 @@ interface EventBlockTimerProps {
|
||||
|
||||
function TimeInputFlow(props: EventBlockTimerProps) {
|
||||
const { eventId, countToEnd, timeStart, timeEnd, duration, timeStrategy, linkStart, delay, showLabels } = props;
|
||||
const { updateEvent, updateTimer } = useEventAction();
|
||||
const { updateEntry, updateTimer } = useEntryActions();
|
||||
|
||||
// In sync with EventEditorTimes
|
||||
const handleSubmit = (field: TimeField, value: string) => {
|
||||
@@ -34,11 +34,11 @@ function TimeInputFlow(props: EventBlockTimerProps) {
|
||||
};
|
||||
|
||||
const handleChangeStrategy = (timeStrategy: TimeStrategy) => {
|
||||
updateEvent({ id: eventId, timeStrategy });
|
||||
updateEntry({ id: eventId, timeStrategy });
|
||||
};
|
||||
|
||||
const handleLink = (doLink: boolean) => {
|
||||
updateEvent({ id: eventId, linkStart: doLink });
|
||||
updateEntry({ id: eventId, linkStart: doLink });
|
||||
};
|
||||
|
||||
const warnings = [];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MouseEvent } from 'react';
|
||||
import { isOntimeEvent, MaybeNumber, MaybeString, OntimeEvent, Rundown } from 'ontime-types';
|
||||
import { EntryId, isOntimeEvent, MaybeNumber, MaybeString, Rundown } from 'ontime-types';
|
||||
import { create } from 'zustand';
|
||||
|
||||
import { RUNDOWN } from '../../common/api/constants';
|
||||
@@ -66,11 +66,11 @@ export const useEventSelection = create<EventSelectionStore>()((set, get) => ({
|
||||
if (!rundownData) return;
|
||||
|
||||
// get list of rundown with only ontime events
|
||||
const events: OntimeEvent[] = [];
|
||||
rundownData.order.forEach((eventId) => {
|
||||
const eventIds: EntryId[] = [];
|
||||
rundownData.flatOrder.forEach((eventId) => {
|
||||
const event = rundownData.entries[eventId];
|
||||
if (isOntimeEvent(event)) {
|
||||
events.push(event);
|
||||
eventIds.push(event.id);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -78,7 +78,7 @@ export const useEventSelection = create<EventSelectionStore>()((set, get) => ({
|
||||
const end = anchoredIndex === null ? index : Math.max(anchoredIndex, index + 1);
|
||||
|
||||
// create new set with range of ids from start to end
|
||||
const selectedEventIds = events.slice(start, end).map((event) => event.id);
|
||||
const selectedEventIds = eventIds.slice(start, end);
|
||||
|
||||
return set({
|
||||
selectedEvents: new Set([...selectedEvents, ...selectedEventIds]),
|
||||
|
||||
Reference in New Issue
Block a user