mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 14:14:17 +00:00
chore: improve convention entry <> event
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import axios, { AxiosResponse } from 'axios';
|
import axios, { AxiosResponse } from 'axios';
|
||||||
import {
|
import {
|
||||||
|
EntryId,
|
||||||
MessageResponse,
|
MessageResponse,
|
||||||
OntimeEntry,
|
OntimeEntry,
|
||||||
OntimeEvent,
|
OntimeEvent,
|
||||||
@@ -29,16 +30,16 @@ export async function fetchCurrentRundown(): Promise<Rundown> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP request to post new event
|
* HTTP request to post new entry
|
||||||
*/
|
*/
|
||||||
export async function requestPostEvent(data: TransientEventPayload): Promise<AxiosResponse<OntimeEntry>> {
|
export async function postAddEntry(data: TransientEventPayload): Promise<AxiosResponse<OntimeEntry>> {
|
||||||
return axios.post(rundownPath, data);
|
return axios.post(rundownPath, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP request to put new event
|
* HTTP request to edit an entry
|
||||||
*/
|
*/
|
||||||
export async function requestPutEvent(data: Partial<OntimeEntry>): Promise<AxiosResponse<OntimeEntry>> {
|
export async function putEditEntry(data: Partial<OntimeEntry>): Promise<AxiosResponse<OntimeEntry>> {
|
||||||
return axios.put(rundownPath, data);
|
return axios.put(rundownPath, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,9 +49,9 @@ type BatchEditEntry = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP request to put multiple events
|
* HTTP request to edit multiple events
|
||||||
*/
|
*/
|
||||||
export async function requestBatchPutEvents(data: BatchEditEntry): Promise<AxiosResponse<MessageResponse>> {
|
export async function putBatchEditEvents(data: BatchEditEntry): Promise<AxiosResponse<MessageResponse>> {
|
||||||
return axios.put(`${rundownPath}/batch`, data);
|
return axios.put(`${rundownPath}/batch`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,9 +62,9 @@ export type ReorderEntry = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP request to reorder events
|
* HTTP request to reorder an entry
|
||||||
*/
|
*/
|
||||||
export async function requestReorderEvent(data: ReorderEntry): Promise<AxiosResponse<OntimeEntry>> {
|
export async function patchReorderEntry(data: ReorderEntry): Promise<AxiosResponse<OntimeEntry>> {
|
||||||
return axios.patch(`${rundownPath}/reorder`, data);
|
return axios.patch(`${rundownPath}/reorder`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,15 +83,15 @@ export async function requestEventSwap(data: SwapEntry): Promise<AxiosResponse<M
|
|||||||
/**
|
/**
|
||||||
* HTTP request to request application of delay
|
* HTTP request to request application of delay
|
||||||
*/
|
*/
|
||||||
export async function requestApplyDelay(eventId: string): Promise<AxiosResponse<MessageResponse>> {
|
export async function requestApplyDelay(delayId: string): Promise<AxiosResponse<MessageResponse>> {
|
||||||
return axios.patch(`${rundownPath}/applydelay/${eventId}`);
|
return axios.patch(`${rundownPath}/applydelay/${delayId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP request to delete given event
|
* HTTP request to delete entries
|
||||||
*/
|
*/
|
||||||
export async function requestDelete(eventIds: string[]): Promise<AxiosResponse<MessageResponse>> {
|
export async function deleteEntries(entryIds: EntryId[]): Promise<AxiosResponse<MessageResponse>> {
|
||||||
return axios.delete(rundownPath, { data: { ids: eventIds } });
|
return axios.delete(rundownPath, { data: { ids: entryIds } });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { addLog } from '../stores/logger';
|
|||||||
import { nowInMillis } from '../utils/time';
|
import { nowInMillis } from '../utils/time';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility unrwap a potential axios error
|
* Utility unwrap a potential axios error
|
||||||
* @param error
|
* @param error
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
@@ -34,7 +34,7 @@ export function maybeAxiosError(error: unknown) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility unrwaps a potential axios error and sends to logger
|
* Utility unwraps a potential axios error and sends to logger
|
||||||
* @param prepend
|
* @param prepend
|
||||||
* @param error
|
* @param error
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { KeyboardEvent, useEffect, useRef, useState } from 'react';
|
|||||||
import { Input, Radio, RadioGroup } from '@chakra-ui/react';
|
import { Input, Radio, RadioGroup } from '@chakra-ui/react';
|
||||||
import { millisToString, parseUserTime } from 'ontime-utils';
|
import { millisToString, parseUserTime } from 'ontime-utils';
|
||||||
|
|
||||||
import { useEventAction } from '../../../hooks/useEventAction';
|
import { useEntryActions } from '../../../hooks/useEntryAction';
|
||||||
|
|
||||||
import style from './DelayInput.module.scss';
|
import style from './DelayInput.module.scss';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ interface DelayInputProps {
|
|||||||
|
|
||||||
export default function DelayInput(props: DelayInputProps) {
|
export default function DelayInput(props: DelayInputProps) {
|
||||||
const { eventId, duration } = props;
|
const { eventId, duration } = props;
|
||||||
const { updateEvent } = useEventAction();
|
const { updateEntry } = useEntryActions();
|
||||||
|
|
||||||
const [value, setValue] = useState<string>('');
|
const [value, setValue] = useState<string>('');
|
||||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||||
@@ -54,7 +54,7 @@ export default function DelayInput(props: DelayInputProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const submitChange = (value: number) => {
|
const submitChange = (value: number) => {
|
||||||
updateEvent({
|
updateEntry({
|
||||||
id: eventId,
|
id: eventId,
|
||||||
duration: value,
|
duration: value,
|
||||||
});
|
});
|
||||||
|
|||||||
+89
-89
@@ -1,10 +1,9 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import {
|
import {
|
||||||
|
EntryId,
|
||||||
isOntimeEvent,
|
isOntimeEvent,
|
||||||
MaybeString,
|
MaybeString,
|
||||||
OntimeBlock,
|
|
||||||
OntimeDelay,
|
|
||||||
OntimeEntry,
|
OntimeEntry,
|
||||||
OntimeEvent,
|
OntimeEvent,
|
||||||
Rundown,
|
Rundown,
|
||||||
@@ -16,15 +15,15 @@ import { dayInMs, MILLIS_PER_SECOND, parseUserTime, reorderArray, swapEventData
|
|||||||
|
|
||||||
import { RUNDOWN } from '../api/constants';
|
import { RUNDOWN } from '../api/constants';
|
||||||
import {
|
import {
|
||||||
|
deleteEntries,
|
||||||
|
patchReorderEntry,
|
||||||
|
postAddEntry,
|
||||||
|
putBatchEditEvents,
|
||||||
|
putEditEntry,
|
||||||
ReorderEntry,
|
ReorderEntry,
|
||||||
requestApplyDelay,
|
requestApplyDelay,
|
||||||
requestBatchPutEvents,
|
|
||||||
requestDelete,
|
|
||||||
requestDeleteAll,
|
requestDeleteAll,
|
||||||
requestEventSwap,
|
requestEventSwap,
|
||||||
requestPostEvent,
|
|
||||||
requestPutEvent,
|
|
||||||
requestReorderEvent,
|
|
||||||
SwapEntry,
|
SwapEntry,
|
||||||
} from '../api/rundown';
|
} from '../api/rundown';
|
||||||
import { logAxiosError } from '../api/utils';
|
import { logAxiosError } from '../api/utils';
|
||||||
@@ -41,9 +40,9 @@ export type EventOptions = Partial<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Set of utilities for events //TODO: should this be called useEntryAction and so on
|
* Gather utilities for actions on entries
|
||||||
*/
|
*/
|
||||||
export const useEventAction = () => {
|
export const useEntryActions = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const {
|
const {
|
||||||
defaultPublic,
|
defaultPublic,
|
||||||
@@ -56,8 +55,8 @@ export const useEventAction = () => {
|
|||||||
defaultEndAction,
|
defaultEndAction,
|
||||||
} = useEditorSettings();
|
} = useEditorSettings();
|
||||||
|
|
||||||
const getEventById = useCallback(
|
const getEntryById = useCallback(
|
||||||
(eventId: string) => {
|
(eventId: string): OntimeEntry | undefined => {
|
||||||
const cachedRundown = queryClient.getQueryData<Rundown>(RUNDOWN);
|
const cachedRundown = queryClient.getQueryData<Rundown>(RUNDOWN);
|
||||||
if (!cachedRundown?.entries) {
|
if (!cachedRundown?.entries) {
|
||||||
return;
|
return;
|
||||||
@@ -68,11 +67,11 @@ export const useEventAction = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls mutation to add new event
|
* Calls mutation to add new entry
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const _addEventMutation = useMutation({
|
const _addEntryMutation = useMutation({
|
||||||
mutationFn: requestPostEvent,
|
mutationFn: postAddEntry,
|
||||||
onSettled: () => {
|
onSettled: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: RUNDOWN });
|
queryClient.invalidateQueries({ queryKey: RUNDOWN });
|
||||||
},
|
},
|
||||||
@@ -80,14 +79,14 @@ export const useEventAction = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an event to rundown
|
* Adds an entry to rundown
|
||||||
*/
|
*/
|
||||||
const addEvent = useCallback(
|
const addEntry = useCallback(
|
||||||
async (event: Partial<OntimeEvent | OntimeDelay | OntimeBlock>, options?: EventOptions) => {
|
async (entry: Partial<OntimeEntry>, options?: EventOptions) => {
|
||||||
const newEvent: TransientEventPayload = { ...event };
|
const newEntry: TransientEventPayload = { ...entry };
|
||||||
|
|
||||||
// ************* CHECK OPTIONS specific to events
|
// ************* CHECK OPTIONS specific to events
|
||||||
if (isOntimeEvent(newEvent)) {
|
if (isOntimeEvent(newEntry)) {
|
||||||
// merge creation time options with event settings
|
// merge creation time options with event settings
|
||||||
const applicationOptions = {
|
const applicationOptions = {
|
||||||
after: options?.after,
|
after: options?.after,
|
||||||
@@ -102,57 +101,57 @@ export const useEventAction = () => {
|
|||||||
const rundownData = queryClient.getQueryData<Rundown>(RUNDOWN)!;
|
const rundownData = queryClient.getQueryData<Rundown>(RUNDOWN)!;
|
||||||
const previousEvent = rundownData.entries[applicationOptions.lastEventId];
|
const previousEvent = rundownData.entries[applicationOptions.lastEventId];
|
||||||
if (isOntimeEvent(previousEvent)) {
|
if (isOntimeEvent(previousEvent)) {
|
||||||
newEvent.timeStart = previousEvent.timeEnd;
|
newEntry.timeStart = previousEvent.timeEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override event with options from editor settings
|
// Override event with options from editor settings
|
||||||
newEvent.linkStart = applicationOptions.linkPrevious;
|
newEntry.linkStart = applicationOptions.linkPrevious;
|
||||||
newEvent.isPublic = applicationOptions.defaultPublic;
|
newEntry.isPublic = applicationOptions.defaultPublic;
|
||||||
|
|
||||||
if (newEvent.duration === undefined && newEvent.timeEnd === undefined) {
|
if (newEntry.duration === undefined && newEntry.timeEnd === undefined) {
|
||||||
newEvent.duration = parseUserTime(defaultDuration);
|
newEntry.duration = parseUserTime(defaultDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEvent.timeDanger === undefined) {
|
if (newEntry.timeDanger === undefined) {
|
||||||
newEvent.timeDanger = parseUserTime(defaultDangerTime);
|
newEntry.timeDanger = parseUserTime(defaultDangerTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEvent.timeWarning === undefined) {
|
if (newEntry.timeWarning === undefined) {
|
||||||
newEvent.timeWarning = parseUserTime(defaultWarnTime);
|
newEntry.timeWarning = parseUserTime(defaultWarnTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEvent.timerType === undefined) {
|
if (newEntry.timerType === undefined) {
|
||||||
newEvent.timerType = defaultTimerType;
|
newEntry.timerType = defaultTimerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEvent.endAction === undefined) {
|
if (newEntry.endAction === undefined) {
|
||||||
newEvent.endAction = defaultEndAction;
|
newEntry.endAction = defaultEndAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEvent.timeStrategy === undefined) {
|
if (newEntry.timeStrategy === undefined) {
|
||||||
newEvent.timeStrategy = defaultTimeStrategy;
|
newEntry.timeStrategy = defaultTimeStrategy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle adding options that concern all event type
|
// handle adding options that concern all event type
|
||||||
if (options?.after) {
|
if (options?.after) {
|
||||||
// @ts-expect-error -- not sure how to type this, <after> is a transient property
|
// @ts-expect-error -- not sure how to type this, <after> is a transient property
|
||||||
newEvent.after = options.after;
|
newEntry.after = options.after;
|
||||||
}
|
}
|
||||||
if (options?.before) {
|
if (options?.before) {
|
||||||
// @ts-expect-error -- not sure how to type this, <before> is a transient property
|
// @ts-expect-error -- not sure how to type this, <before> is a transient property
|
||||||
newEvent.before = options.before;
|
newEntry.before = options.before;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await _addEventMutation.mutateAsync(newEvent as TransientEventPayload);
|
await _addEntryMutation.mutateAsync(newEntry as TransientEventPayload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logAxiosError('Failed adding event', error);
|
logAxiosError('Failed adding event', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
_addEventMutation,
|
_addEntryMutation,
|
||||||
defaultDangerTime,
|
defaultDangerTime,
|
||||||
defaultDuration,
|
defaultDuration,
|
||||||
defaultEndAction,
|
defaultEndAction,
|
||||||
@@ -166,11 +165,11 @@ export const useEventAction = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls mutation to update existing event
|
* Calls mutation to update existing entry
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const _updateEventMutation = useMutation({
|
const _updateEntryMutation = useMutation({
|
||||||
mutationFn: requestPutEvent,
|
mutationFn: putEditEntry,
|
||||||
// we optimistically update here
|
// we optimistically update here
|
||||||
onMutate: async (newEvent) => {
|
onMutate: async (newEvent) => {
|
||||||
// cancel ongoing queries
|
// cancel ongoing queries
|
||||||
@@ -210,35 +209,35 @@ export const useEventAction = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates existing event
|
* Updates existing entry
|
||||||
*/
|
*/
|
||||||
const updateEvent = useCallback(
|
const updateEntry = useCallback(
|
||||||
async (event: Partial<OntimeEntry>) => {
|
async (event: Partial<OntimeEntry>) => {
|
||||||
try {
|
try {
|
||||||
await _updateEventMutation.mutateAsync(event);
|
await _updateEntryMutation.mutateAsync(event);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logAxiosError('Error updating event', error);
|
logAxiosError('Error updating event', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_updateEventMutation],
|
[_updateEntryMutation],
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateCustomField = useCallback(
|
const updateCustomField = useCallback(
|
||||||
async (eventId: string, field: string, value: string) => {
|
async (entryId: EntryId, field: string, value: string) => {
|
||||||
updateEvent({ id: eventId, custom: { [field]: value } });
|
updateEntry({ id: entryId, custom: { [field]: value } });
|
||||||
},
|
},
|
||||||
[updateEvent],
|
[updateEntry],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates time of existing event
|
* Updates time of existing event
|
||||||
* @param eventId {string} - id of the event
|
* @param eventId {EntryId} - id of the event
|
||||||
* @param field {TimeField} - field to update
|
* @param field {TimeField} - field to update
|
||||||
* @param value {string} - new value string to be parsed
|
* @param value {string} - new value string to be parsed
|
||||||
* @param lockOnUpdate {boolean} - whether we will apply the lock / release on update
|
* @param lockOnUpdate {boolean} - whether we will apply the lock / release on update
|
||||||
*/
|
*/
|
||||||
const updateTimer = useCallback(
|
const updateTimer = useCallback(
|
||||||
async (eventId: string, field: TimeField, value: string, lockOnUpdate?: boolean) => {
|
async (eventId: EntryId, field: TimeField, value: string, lockOnUpdate?: boolean) => {
|
||||||
// an empty value with no lock has no domain validity
|
// an empty value with no lock has no domain validity
|
||||||
if (!lockOnUpdate && value === '') {
|
if (!lockOnUpdate && value === '') {
|
||||||
return;
|
return;
|
||||||
@@ -268,7 +267,7 @@ export const useEventAction = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await _updateEventMutation.mutateAsync(newEvent);
|
await _updateEntryMutation.mutateAsync(newEvent);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logAxiosError('Error updating event', error);
|
logAxiosError('Error updating event', error);
|
||||||
}
|
}
|
||||||
@@ -320,7 +319,7 @@ export const useEventAction = () => {
|
|||||||
return previousEnd;
|
return previousEnd;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_updateEventMutation, queryClient],
|
[_updateEntryMutation, queryClient],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -328,7 +327,7 @@ export const useEventAction = () => {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const _batchUpdateEventsMutation = useMutation({
|
const _batchUpdateEventsMutation = useMutation({
|
||||||
mutationFn: requestBatchPutEvents,
|
mutationFn: putBatchEditEvents,
|
||||||
onMutate: async ({ ids, data }) => {
|
onMutate: async ({ ids, data }) => {
|
||||||
// cancel ongoing queries
|
// cancel ongoing queries
|
||||||
await queryClient.cancelQueries({ queryKey: RUNDOWN });
|
await queryClient.cancelQueries({ queryKey: RUNDOWN });
|
||||||
@@ -360,6 +359,7 @@ export const useEventAction = () => {
|
|||||||
revision: -1,
|
revision: -1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a context with the previous rundown
|
// Return a context with the previous rundown
|
||||||
return { previousRundown };
|
return { previousRundown };
|
||||||
},
|
},
|
||||||
@@ -384,13 +384,13 @@ export const useEventAction = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls mutation to delete an event
|
* Calls mutation to delete an entry
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const _deleteEventMutation = useMutation({
|
const _deleteEntryMutation = useMutation({
|
||||||
mutationFn: requestDelete,
|
mutationFn: deleteEntries,
|
||||||
// we optimistically update here
|
// we optimistically update here
|
||||||
onMutate: async (eventIds: string[]) => {
|
onMutate: async (entryIds: EntryId[]) => {
|
||||||
// cancel ongoing queries
|
// cancel ongoing queries
|
||||||
await queryClient.cancelQueries({ queryKey: RUNDOWN });
|
await queryClient.cancelQueries({ queryKey: RUNDOWN });
|
||||||
|
|
||||||
@@ -399,9 +399,9 @@ export const useEventAction = () => {
|
|||||||
|
|
||||||
if (previousData) {
|
if (previousData) {
|
||||||
// optimistically update object
|
// optimistically update object
|
||||||
const newOrder = previousData.order.filter((id) => !eventIds.includes(id));
|
const newOrder = previousData.order.filter((id) => !entryIds.includes(id));
|
||||||
const newRundown = { ...previousData.entries };
|
const newRundown = { ...previousData.entries };
|
||||||
for (const eventId of eventIds) {
|
for (const eventId of entryIds) {
|
||||||
delete newRundown[eventId];
|
delete newRundown[eventId];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ export const useEventAction = () => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Mutation fails, rollback undoes optimist update
|
// Mutation fails, rollback undoes optimist update
|
||||||
onError: (_error, _eventId, context) => {
|
onError: (_error, _entryIds, context) => {
|
||||||
queryClient.setQueryData<Rundown>(RUNDOWN, context?.previousData);
|
queryClient.setQueryData<Rundown>(RUNDOWN, context?.previousData);
|
||||||
},
|
},
|
||||||
// Mutation finished, failed or successful
|
// Mutation finished, failed or successful
|
||||||
@@ -431,24 +431,24 @@ export const useEventAction = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes an event form the list
|
* Deletes an event entry from the rundown
|
||||||
*/
|
*/
|
||||||
const deleteEvent = useCallback(
|
const deleteEntry = useCallback(
|
||||||
async (eventIds: string[]) => {
|
async (entryIds: EntryId[]) => {
|
||||||
try {
|
try {
|
||||||
await _deleteEventMutation.mutateAsync(eventIds);
|
await _deleteEntryMutation.mutateAsync(entryIds);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logAxiosError('Error deleting event', error);
|
logAxiosError('Error deleting event', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_deleteEventMutation],
|
[_deleteEntryMutation],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls mutation to delete all events
|
* Calls mutation to delete all events
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const _deleteAllEventsMutation = useMutation({
|
const _deleteAllEntriesMutation = useMutation({
|
||||||
mutationFn: requestDeleteAll,
|
mutationFn: requestDeleteAll,
|
||||||
// we optimistically update here
|
// we optimistically update here
|
||||||
onMutate: async () => {
|
onMutate: async () => {
|
||||||
@@ -471,8 +471,8 @@ export const useEventAction = () => {
|
|||||||
return { previousData };
|
return { previousData };
|
||||||
},
|
},
|
||||||
|
|
||||||
// Mutation fails, rollback undos optimist update
|
// Mutation fails, rollback optimist update
|
||||||
onError: (_error, _eventId, context) => {
|
onError: (_error, _, context) => {
|
||||||
queryClient.setQueryData<Rundown>(RUNDOWN, context?.previousData);
|
queryClient.setQueryData<Rundown>(RUNDOWN, context?.previousData);
|
||||||
},
|
},
|
||||||
// Mutation finished, failed or successful
|
// Mutation finished, failed or successful
|
||||||
@@ -484,15 +484,15 @@ export const useEventAction = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all events from list
|
* Deletes all entries in the rundown
|
||||||
*/
|
*/
|
||||||
const deleteAllEvents = useCallback(async () => {
|
const deleteAllEntries = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
await _deleteAllEventsMutation.mutateAsync();
|
await _deleteAllEntriesMutation.mutateAsync();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logAxiosError('Error deleting events', error);
|
logAxiosError('Error deleting events', error);
|
||||||
}
|
}
|
||||||
}, [_deleteAllEventsMutation]);
|
}, [_deleteAllEntriesMutation]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls mutation to apply a delay
|
* Calls mutation to apply a delay
|
||||||
@@ -508,7 +508,7 @@ export const useEventAction = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a given delay block
|
* Applies a given delay
|
||||||
*/
|
*/
|
||||||
const applyDelay = useCallback(
|
const applyDelay = useCallback(
|
||||||
async (delayEventId: string) => {
|
async (delayEventId: string) => {
|
||||||
@@ -522,11 +522,11 @@ export const useEventAction = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls mutation to reorder an event
|
* Calls mutation to reorder an entry
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const _reorderEventMutation = useMutation({
|
const _reorderEntryMutation = useMutation({
|
||||||
mutationFn: requestReorderEvent,
|
mutationFn: patchReorderEntry,
|
||||||
// we optimistically update here
|
// we optimistically update here
|
||||||
onMutate: async (data) => {
|
onMutate: async (data) => {
|
||||||
// cancel ongoing queries
|
// cancel ongoing queries
|
||||||
@@ -552,7 +552,7 @@ export const useEventAction = () => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Mutation fails, rollback undoes optimist update
|
// Mutation fails, rollback undoes optimist update
|
||||||
onError: (_error, _eventId, context) => {
|
onError: (_error, _data, context) => {
|
||||||
queryClient.setQueryData<Rundown>(RUNDOWN, context?.previousData);
|
queryClient.setQueryData<Rundown>(RUNDOWN, context?.previousData);
|
||||||
},
|
},
|
||||||
// Mutation finished, failed or successful
|
// Mutation finished, failed or successful
|
||||||
@@ -564,22 +564,22 @@ export const useEventAction = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reorders a given event
|
* Reorders a given entry
|
||||||
*/
|
*/
|
||||||
const reorderEvent = useCallback(
|
const reorderEntry = useCallback(
|
||||||
async (eventId: string, from: number, to: number) => {
|
async (entryId: string, from: number, to: number) => {
|
||||||
try {
|
try {
|
||||||
const reorderObject: ReorderEntry = {
|
const reorderObject: ReorderEntry = {
|
||||||
eventId,
|
eventId: entryId,
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
};
|
};
|
||||||
await _reorderEventMutation.mutateAsync(reorderObject);
|
await _reorderEntryMutation.mutateAsync(reorderObject);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logAxiosError('Error re-ordering event', error);
|
logAxiosError('Error re-ordering event', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_reorderEventMutation],
|
[_reorderEntryMutation],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -649,15 +649,15 @@ export const useEventAction = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addEvent,
|
addEntry,
|
||||||
applyDelay,
|
applyDelay,
|
||||||
batchUpdateEvents,
|
batchUpdateEvents,
|
||||||
deleteEvent,
|
deleteEntry,
|
||||||
deleteAllEvents,
|
deleteAllEntries,
|
||||||
getEventById,
|
getEntryById,
|
||||||
reorderEvent,
|
reorderEntry,
|
||||||
swapEvents,
|
swapEvents,
|
||||||
updateEvent,
|
updateEntry,
|
||||||
updateTimer,
|
updateTimer,
|
||||||
updateCustomField,
|
updateCustomField,
|
||||||
};
|
};
|
||||||
@@ -2,7 +2,7 @@ import { useRef, useState } from 'react';
|
|||||||
import { Button, Textarea } from '@chakra-ui/react';
|
import { Button, Textarea } from '@chakra-ui/react';
|
||||||
import { OntimeEvent } from 'ontime-types';
|
import { OntimeEvent } from 'ontime-types';
|
||||||
|
|
||||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||||
import type { EditEvent } from '../Operator';
|
import type { EditEvent } from '../Operator';
|
||||||
|
|
||||||
import style from './EditModal.module.scss';
|
import style from './EditModal.module.scss';
|
||||||
@@ -15,7 +15,7 @@ interface EditModalProps {
|
|||||||
export default function EditModal(props: EditModalProps) {
|
export default function EditModal(props: EditModalProps) {
|
||||||
const { event, onClose } = props;
|
const { event, onClose } = props;
|
||||||
|
|
||||||
const { updateEvent } = useEventAction();
|
const { updateEntry } = useEntryActions();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const inputRef = useRef<HTMLTextAreaElement[]>(new Array<HTMLTextAreaElement>());
|
const inputRef = useRef<HTMLTextAreaElement[]>(new Array<HTMLTextAreaElement>());
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export default function EditModal(props: EditModalProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (patchObject.custom) {
|
if (patchObject.custom) {
|
||||||
await updateEvent(patchObject);
|
await updateEntry(patchObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
reorderArray,
|
reorderArray,
|
||||||
} from 'ontime-utils';
|
} 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 useFollowComponent from '../../common/hooks/useFollowComponent';
|
||||||
import { useRundownEditor } from '../../common/hooks/useSocket';
|
import { useRundownEditor } from '../../common/hooks/useSocket';
|
||||||
import { AppMode, useAppMode } from '../../common/stores/appModeStore';
|
import { AppMode, useAppMode } from '../../common/stores/appModeStore';
|
||||||
@@ -48,7 +48,7 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
const [statefulEntries, setStatefulEntries] = useState<EntryId[]>(order);
|
const [statefulEntries, setStatefulEntries] = useState<EntryId[]>(order);
|
||||||
|
|
||||||
const featureData = useRundownEditor();
|
const featureData = useRundownEditor();
|
||||||
const { addEvent, reorderEvent, deleteEvent } = useEventAction();
|
const { addEntry, reorderEntry, deleteEntry } = useEntryActions();
|
||||||
|
|
||||||
const { entryCopyId, setEntryCopyId } = useEntryCopy();
|
const { entryCopyId, setEntryCopyId } = useEntryCopy();
|
||||||
|
|
||||||
@@ -67,12 +67,12 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
(cursor: string | null) => {
|
(cursor: string | null) => {
|
||||||
if (!cursor) return;
|
if (!cursor) return;
|
||||||
const { entry, index } = getPreviousNormal(entries, order, cursor);
|
const { entry, index } = getPreviousNormal(entries, order, cursor);
|
||||||
deleteEvent([cursor]);
|
deleteEntry([cursor]);
|
||||||
if (entry && index !== null) {
|
if (entry && index !== null) {
|
||||||
setSelectedEvents({ id: entry.id, selectMode: 'click', index });
|
setSelectedEvents({ id: entry.id, selectMode: 'click', index });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[entries, order, deleteEvent, setSelectedEvents],
|
[entries, order, deleteEntry, setSelectedEvents],
|
||||||
);
|
);
|
||||||
|
|
||||||
const insertCopyAtId = useCallback(
|
const insertCopyAtId = useCallback(
|
||||||
@@ -86,10 +86,10 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
if (cloneEntry?.type === SupportedEvent.Event) {
|
if (cloneEntry?.type === SupportedEvent.Event) {
|
||||||
//if we don't have a cursor add the new event on top
|
//if we don't have a cursor add the new event on top
|
||||||
const newEvent = cloneEvent(cloneEntry);
|
const newEvent = cloneEvent(cloneEntry);
|
||||||
addEvent(newEvent, { after: adjustedCursor ?? undefined });
|
addEntry(newEvent, { after: adjustedCursor ?? undefined });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[addEvent, order, entries],
|
[addEntry, order, entries],
|
||||||
);
|
);
|
||||||
|
|
||||||
const insertAtId = useCallback(
|
const insertAtId = useCallback(
|
||||||
@@ -109,12 +109,12 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
if (!above && id) {
|
if (!above && id) {
|
||||||
options.lastEventId = id;
|
options.lastEventId = id;
|
||||||
}
|
}
|
||||||
addEvent(newEvent, options);
|
addEntry(newEvent, options);
|
||||||
} else {
|
} else {
|
||||||
addEvent({ type }, options);
|
addEntry({ type }, options);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[addEvent],
|
[addEntry],
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectBlock = useCallback(
|
const selectBlock = useCallback(
|
||||||
@@ -187,10 +187,10 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
|
|
||||||
if (index !== null) {
|
if (index !== null) {
|
||||||
const offsetIndex = direction === 'up' ? index + 1 : index - 1;
|
const offsetIndex = direction === 'up' ? index + 1 : index - 1;
|
||||||
reorderEvent(cursor, offsetIndex, index);
|
reorderEntry(cursor, offsetIndex, index);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[order, reorderEvent, entries],
|
[order, reorderEntry, entries],
|
||||||
);
|
);
|
||||||
|
|
||||||
// shortcuts
|
// shortcuts
|
||||||
@@ -254,7 +254,7 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
setStatefulEntries((currentEntries) => {
|
setStatefulEntries((currentEntries) => {
|
||||||
return reorderArray(currentEntries, fromIndex, toIndex);
|
return reorderArray(currentEntries, fromIndex, toIndex);
|
||||||
});
|
});
|
||||||
reorderEvent(String(active.id), fromIndex, toIndex);
|
reorderEntry(String(active.id), fromIndex, toIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
SupportedEvent,
|
SupportedEvent,
|
||||||
} from 'ontime-types';
|
} from 'ontime-types';
|
||||||
|
|
||||||
import { useEventAction } from '../../common/hooks/useEventAction';
|
import { useEntryActions } from '../../common/hooks/useEntryAction';
|
||||||
import useMemoisedFn from '../../common/hooks/useMemoisedFn';
|
import useMemoisedFn from '../../common/hooks/useMemoisedFn';
|
||||||
import { useEmitLog } from '../../common/stores/logger';
|
import { useEmitLog } from '../../common/stores/logger';
|
||||||
import { cloneEvent } from '../../common/utils/eventsManager';
|
import { cloneEvent } from '../../common/utils/eventsManager';
|
||||||
@@ -66,7 +66,7 @@ export default function RundownEntry(props: RundownEntryProps) {
|
|||||||
isLinkedToLoaded,
|
isLinkedToLoaded,
|
||||||
} = props;
|
} = props;
|
||||||
const { emitError } = useEmitLog();
|
const { emitError } = useEmitLog();
|
||||||
const { addEvent, updateEvent, batchUpdateEvents, deleteEvent, swapEvents } = useEventAction();
|
const { addEntry, updateEntry, batchUpdateEvents, deleteEntry, swapEvents } = useEntryActions();
|
||||||
const { selectedEvents, unselect, clearSelectedEvents } = useEventSelection();
|
const { selectedEvents, unselect, clearSelectedEvents } = useEventSelection();
|
||||||
|
|
||||||
const removeOpenEvent = useCallback(() => {
|
const removeOpenEvent = useCallback(() => {
|
||||||
@@ -91,26 +91,26 @@ export default function RundownEntry(props: RundownEntryProps) {
|
|||||||
after: data.id,
|
after: data.id,
|
||||||
lastEventId: previousEventId,
|
lastEventId: previousEventId,
|
||||||
};
|
};
|
||||||
return addEvent(newEvent, options);
|
return addEntry(newEvent, options);
|
||||||
}
|
}
|
||||||
case 'event-before': {
|
case 'event-before': {
|
||||||
const newEvent = { type: SupportedEvent.Event };
|
const newEvent = { type: SupportedEvent.Event };
|
||||||
const options = {
|
const options = {
|
||||||
after: previousEntryId,
|
after: previousEntryId,
|
||||||
};
|
};
|
||||||
return addEvent(newEvent, options);
|
return addEntry(newEvent, options);
|
||||||
}
|
}
|
||||||
case 'delay': {
|
case 'delay': {
|
||||||
return addEvent({ type: SupportedEvent.Delay }, { after: data.id });
|
return addEntry({ type: SupportedEvent.Delay }, { after: data.id });
|
||||||
}
|
}
|
||||||
case 'delay-before': {
|
case 'delay-before': {
|
||||||
return addEvent({ type: SupportedEvent.Delay }, { after: previousEntryId });
|
return addEntry({ type: SupportedEvent.Delay }, { after: previousEntryId });
|
||||||
}
|
}
|
||||||
case 'block': {
|
case 'block': {
|
||||||
return addEvent({ type: SupportedEvent.Block }, { after: data.id });
|
return addEntry({ type: SupportedEvent.Block }, { after: data.id });
|
||||||
}
|
}
|
||||||
case 'block-before': {
|
case 'block-before': {
|
||||||
return addEvent({ type: SupportedEvent.Block }, { after: previousEntryId });
|
return addEntry({ type: SupportedEvent.Block }, { after: previousEntryId });
|
||||||
}
|
}
|
||||||
case 'swap': {
|
case 'swap': {
|
||||||
const { value } = payload as FieldValue;
|
const { value } = payload as FieldValue;
|
||||||
@@ -119,14 +119,14 @@ export default function RundownEntry(props: RundownEntryProps) {
|
|||||||
case 'delete': {
|
case 'delete': {
|
||||||
if (selectedEvents.size > 1) {
|
if (selectedEvents.size > 1) {
|
||||||
clearMultiSelection();
|
clearMultiSelection();
|
||||||
return deleteEvent(Array.from(selectedEvents));
|
return deleteEntry(Array.from(selectedEvents));
|
||||||
}
|
}
|
||||||
removeOpenEvent();
|
removeOpenEvent();
|
||||||
return deleteEvent([data.id]);
|
return deleteEntry([data.id]);
|
||||||
}
|
}
|
||||||
case 'clone': {
|
case 'clone': {
|
||||||
const newEvent = cloneEvent(data as OntimeEvent);
|
const newEvent = cloneEvent(data as OntimeEvent);
|
||||||
addEvent(newEvent, { after: data.id });
|
addEntry(newEvent, { after: data.id });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'update': {
|
case 'update': {
|
||||||
@@ -147,7 +147,7 @@ export default function RundownEntry(props: RundownEntryProps) {
|
|||||||
if (field in data) {
|
if (field in data) {
|
||||||
// @ts-expect-error -- not sure how to type this
|
// @ts-expect-error -- not sure how to type this
|
||||||
newData[field] = value;
|
newData[field] = value;
|
||||||
return updateEvent(newData);
|
return updateEntry(newData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return emitError(`Unknown field: ${field}`);
|
return emitError(`Unknown field: ${field}`);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useCallback, useRef } from 'react';
|
|||||||
import { Input } from '@chakra-ui/react';
|
import { Input } from '@chakra-ui/react';
|
||||||
|
|
||||||
import useReactiveTextInput from '../../../common/components/input/text-input/useReactiveTextInput';
|
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 { cx } from '../../../common/utils/styleUtils';
|
||||||
|
|
||||||
import style from './TitleEditor.module.scss';
|
import style from './TitleEditor.module.scss';
|
||||||
@@ -16,7 +16,7 @@ interface TitleEditorProps {
|
|||||||
|
|
||||||
export default function EditableBlockTitle(props: TitleEditorProps) {
|
export default function EditableBlockTitle(props: TitleEditorProps) {
|
||||||
const { title, eventId, placeholder, className } = props;
|
const { title, eventId, placeholder, className } = props;
|
||||||
const { updateEvent } = useEventAction();
|
const { updateEntry } = useEntryActions();
|
||||||
const ref = useRef<HTMLInputElement | null>(null);
|
const ref = useRef<HTMLInputElement | null>(null);
|
||||||
const submitCallback = useCallback(
|
const submitCallback = useCallback(
|
||||||
(text: string) => {
|
(text: string) => {
|
||||||
@@ -25,9 +25,9 @@ export default function EditableBlockTitle(props: TitleEditorProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cleanVal = text.trim();
|
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, {
|
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 { OntimeDelay } from 'ontime-types';
|
||||||
|
|
||||||
import DelayInput from '../../../common/components/input/delay-input/DelayInput';
|
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 { cx } from '../../../common/utils/styleUtils';
|
||||||
|
|
||||||
import style from './DelayBlock.module.scss';
|
import style from './DelayBlock.module.scss';
|
||||||
@@ -18,7 +18,7 @@ interface DelayBlockProps {
|
|||||||
|
|
||||||
export default function DelayBlock(props: DelayBlockProps) {
|
export default function DelayBlock(props: DelayBlockProps) {
|
||||||
const { data, hasCursor } = props;
|
const { data, hasCursor } = props;
|
||||||
const { applyDelay, deleteEvent } = useEventAction();
|
const { applyDelay, deleteEntry } = useEntryActions();
|
||||||
const handleRef = useRef<null | HTMLSpanElement>(null);
|
const handleRef = useRef<null | HTMLSpanElement>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -48,7 +48,7 @@ export default function DelayBlock(props: DelayBlockProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const cancelDelayHandler = () => {
|
const cancelDelayHandler = () => {
|
||||||
deleteEvent([data.id]);
|
deleteEntry([data.id]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const blockClasses = cx([style.delay, hasCursor ? style.hasCursor : null]);
|
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 { IoPause, IoPlay, IoReload, IoRemoveCircle, IoRemoveCircleOutline } from 'react-icons/io5';
|
||||||
|
|
||||||
import TooltipActionBtn from '../../../../common/components/buttons/TooltipActionBtn';
|
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 { setEventPlayback } from '../../../../common/hooks/useSocket';
|
||||||
import { tooltipDelayMid } from '../../../../ontimeConfig';
|
import { tooltipDelayMid } from '../../../../ontimeConfig';
|
||||||
|
|
||||||
@@ -34,11 +34,11 @@ interface EventBlockPlaybackProps {
|
|||||||
|
|
||||||
const EventBlockPlayback = (props: EventBlockPlaybackProps) => {
|
const EventBlockPlayback = (props: EventBlockPlaybackProps) => {
|
||||||
const { eventId, skip, isPlaying, isPaused, loaded, disablePlayback } = props;
|
const { eventId, skip, isPlaying, isPaused, loaded, disablePlayback } = props;
|
||||||
const { updateEvent } = useEventAction();
|
const { updateEntry } = useEntryActions();
|
||||||
|
|
||||||
const toggleSkip = (event: MouseEvent) => {
|
const toggleSkip = (event: MouseEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
updateEvent({ id: eventId, skip: !skip });
|
updateEntry({ id: eventId, skip: !skip });
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionHandler = (event: MouseEvent) => {
|
const actionHandler = (event: MouseEvent) => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
|
|||||||
import { CustomFieldLabel, OntimeEvent } from 'ontime-types';
|
import { CustomFieldLabel, OntimeEvent } from 'ontime-types';
|
||||||
|
|
||||||
import AppLink from '../../../common/components/link/app-link/AppLink';
|
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 useCustomFields from '../../../common/hooks-query/useCustomFields';
|
||||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ interface EventEditorProps {
|
|||||||
export default function EventEditor(props: EventEditorProps) {
|
export default function EventEditor(props: EventEditorProps) {
|
||||||
const { event } = props;
|
const { event } = props;
|
||||||
const { data: customFields } = useCustomFields();
|
const { data: customFields } = useCustomFields();
|
||||||
const { updateEvent } = useEventAction();
|
const { updateEntry } = useEntryActions();
|
||||||
|
|
||||||
const isEditor = window.location.pathname.includes('editor');
|
const isEditor = window.location.pathname.includes('editor');
|
||||||
|
|
||||||
@@ -31,12 +31,12 @@ export default function EventEditor(props: EventEditorProps) {
|
|||||||
(field: EditorUpdateFields, value: string) => {
|
(field: EditorUpdateFields, value: string) => {
|
||||||
if (field.startsWith('custom-')) {
|
if (field.startsWith('custom-')) {
|
||||||
const fieldLabel = field.split('custom-')[1];
|
const fieldLabel = field.split('custom-')[1];
|
||||||
updateEvent({ id: event?.id, custom: { [fieldLabel]: value } });
|
updateEntry({ id: event?.id, custom: { [fieldLabel]: value } });
|
||||||
} else {
|
} else {
|
||||||
updateEvent({ id: event?.id, [field]: value });
|
updateEntry({ id: event?.id, [field]: value });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[event?.id, updateEvent],
|
[event?.id, updateEntry],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { EndAction, TimerType, TimeStrategy } from 'ontime-types';
|
|||||||
import { millisToString, parseUserTime } from 'ontime-utils';
|
import { millisToString, parseUserTime } from 'ontime-utils';
|
||||||
|
|
||||||
import TimeInput from '../../../../common/components/input/time-input/TimeInput';
|
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 { millisToDelayString } from '../../../../common/utils/dateConfig';
|
||||||
import * as Editor from '../../../editors/editor-utils/EditorUtils';
|
import * as Editor from '../../../editors/editor-utils/EditorUtils';
|
||||||
import TimeInputFlow from '../../time-input-flow/TimeInputFlow';
|
import TimeInputFlow from '../../time-input-flow/TimeInputFlow';
|
||||||
@@ -46,27 +46,27 @@ function EventEditorTimes(props: EventEditorTimesProps) {
|
|||||||
timeWarning,
|
timeWarning,
|
||||||
timeDanger,
|
timeDanger,
|
||||||
} = props;
|
} = props;
|
||||||
const { updateEvent } = useEventAction();
|
const { updateEntry } = useEntryActions();
|
||||||
|
|
||||||
const handleSubmit = (field: HandledActions, value: string | boolean) => {
|
const handleSubmit = (field: HandledActions, value: string | boolean) => {
|
||||||
if (field === 'isPublic') {
|
if (field === 'isPublic') {
|
||||||
updateEvent({ id: eventId, isPublic: !(value as boolean) });
|
updateEntry({ id: eventId, isPublic: !(value as boolean) });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field === 'countToEnd') {
|
if (field === 'countToEnd') {
|
||||||
updateEvent({ id: eventId, countToEnd: !(value as boolean) });
|
updateEntry({ id: eventId, countToEnd: !(value as boolean) });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field === 'timeWarning' || field === 'timeDanger') {
|
if (field === 'timeWarning' || field === 'timeDanger') {
|
||||||
const newTime = parseUserTime(value as string);
|
const newTime = parseUserTime(value as string);
|
||||||
updateEvent({ id: eventId, [field]: newTime });
|
updateEntry({ id: eventId, [field]: newTime });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field === 'timerType' || field === 'endAction') {
|
if (field === 'timerType' || field === 'endAction') {
|
||||||
updateEvent({ id: eventId, [field]: value });
|
updateEntry({ id: eventId, [field]: value });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { IoAdd } from 'react-icons/io5';
|
|||||||
import { Button } from '@chakra-ui/react';
|
import { Button } from '@chakra-ui/react';
|
||||||
import { MaybeString, SupportedEvent } from 'ontime-types';
|
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 { useEmitLog } from '../../../common/stores/logger';
|
||||||
|
|
||||||
import style from './QuickAddBlock.module.scss';
|
import style from './QuickAddBlock.module.scss';
|
||||||
@@ -17,7 +17,7 @@ export default memo(QuickAddBlock);
|
|||||||
|
|
||||||
function QuickAddBlock(props: QuickAddBlockProps) {
|
function QuickAddBlock(props: QuickAddBlockProps) {
|
||||||
const { previousEventId, showBlocks } = props;
|
const { previousEventId, showBlocks } = props;
|
||||||
const { addEvent } = useEventAction();
|
const { addEntry } = useEntryActions();
|
||||||
const { emitError } = useEmitLog();
|
const { emitError } = useEmitLog();
|
||||||
|
|
||||||
const doLinkPrevious = useRef<HTMLInputElement | null>(null);
|
const doLinkPrevious = useRef<HTMLInputElement | null>(null);
|
||||||
@@ -37,7 +37,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
|||||||
lastEventId: previousEventId,
|
lastEventId: previousEventId,
|
||||||
linkPrevious,
|
linkPrevious,
|
||||||
};
|
};
|
||||||
addEvent(newEvent, options);
|
addEntry(newEvent, options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'delay': {
|
case 'delay': {
|
||||||
@@ -45,7 +45,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
|||||||
lastEventId: previousEventId,
|
lastEventId: previousEventId,
|
||||||
after: previousEventId,
|
after: previousEventId,
|
||||||
};
|
};
|
||||||
addEvent({ type: SupportedEvent.Delay }, options);
|
addEntry({ type: SupportedEvent.Delay }, options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'block': {
|
case 'block': {
|
||||||
@@ -53,7 +53,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
|||||||
lastEventId: previousEventId,
|
lastEventId: previousEventId,
|
||||||
after: previousEventId,
|
after: previousEventId,
|
||||||
};
|
};
|
||||||
addEvent({ type: SupportedEvent.Block }, options);
|
addEntry({ type: SupportedEvent.Block }, options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -62,7 +62,7 @@ function QuickAddBlock(props: QuickAddBlockProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[previousEventId, addEvent, emitError],
|
[previousEventId, addEntry, emitError],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,23 +11,23 @@ import {
|
|||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||||
import { useAppMode } from '../../../common/stores/appModeStore';
|
import { useAppMode } from '../../../common/stores/appModeStore';
|
||||||
import { useEventSelection } from '../useEventSelection';
|
import { useEventSelection } from '../useEventSelection';
|
||||||
|
|
||||||
export default function RundownMenu() {
|
export default function RundownMenu() {
|
||||||
const clearSelectedEvents = useEventSelection((state) => state.clearSelectedEvents);
|
const clearSelectedEvents = useEventSelection((state) => state.clearSelectedEvents);
|
||||||
const appMode = useAppMode((state) => state.mode);
|
const appMode = useAppMode((state) => state.mode);
|
||||||
const { deleteAllEvents } = useEventAction();
|
const { deleteAllEntries } = useEntryActions();
|
||||||
|
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const cancelRef = useRef<HTMLButtonElement | null>(null);
|
const cancelRef = useRef<HTMLButtonElement | null>(null);
|
||||||
|
|
||||||
const deleteAll = useCallback(() => {
|
const deleteAll = useCallback(() => {
|
||||||
deleteAllEvents();
|
deleteAllEntries();
|
||||||
clearSelectedEvents();
|
clearSelectedEvents();
|
||||||
onClose();
|
onClose();
|
||||||
}, [clearSelectedEvents, deleteAllEvents, onClose]);
|
}, [clearSelectedEvents, deleteAllEntries, onClose]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { TimeField, TimeStrategy } from 'ontime-types';
|
|||||||
import { dayInMs } from 'ontime-utils';
|
import { dayInMs } from 'ontime-utils';
|
||||||
|
|
||||||
import TimeInputWithButton from '../../../common/components/input/time-input/TimeInputWithButton';
|
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 { cx } from '../../../common/utils/styleUtils';
|
||||||
import { tooltipDelayFast, tooltipDelayMid } from '../../../ontimeConfig';
|
import { tooltipDelayFast, tooltipDelayMid } from '../../../ontimeConfig';
|
||||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
||||||
@@ -26,7 +26,7 @@ interface EventBlockTimerProps {
|
|||||||
|
|
||||||
function TimeInputFlow(props: EventBlockTimerProps) {
|
function TimeInputFlow(props: EventBlockTimerProps) {
|
||||||
const { eventId, countToEnd, timeStart, timeEnd, duration, timeStrategy, linkStart, delay, showLabels } = props;
|
const { eventId, countToEnd, timeStart, timeEnd, duration, timeStrategy, linkStart, delay, showLabels } = props;
|
||||||
const { updateEvent, updateTimer } = useEventAction();
|
const { updateEntry, updateTimer } = useEntryActions();
|
||||||
|
|
||||||
// In sync with EventEditorTimes
|
// In sync with EventEditorTimes
|
||||||
const handleSubmit = (field: TimeField, value: string) => {
|
const handleSubmit = (field: TimeField, value: string) => {
|
||||||
@@ -34,11 +34,11 @@ function TimeInputFlow(props: EventBlockTimerProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleChangeStrategy = (timeStrategy: TimeStrategy) => {
|
const handleChangeStrategy = (timeStrategy: TimeStrategy) => {
|
||||||
updateEvent({ id: eventId, timeStrategy });
|
updateEntry({ id: eventId, timeStrategy });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLink = (doLink: boolean) => {
|
const handleLink = (doLink: boolean) => {
|
||||||
updateEvent({ id: eventId, linkStart: doLink });
|
updateEntry({ id: eventId, linkStart: doLink });
|
||||||
};
|
};
|
||||||
|
|
||||||
const warnings = [];
|
const warnings = [];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { MouseEvent } from 'react';
|
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 { create } from 'zustand';
|
||||||
|
|
||||||
import { RUNDOWN } from '../../common/api/constants';
|
import { RUNDOWN } from '../../common/api/constants';
|
||||||
@@ -66,11 +66,11 @@ export const useEventSelection = create<EventSelectionStore>()((set, get) => ({
|
|||||||
if (!rundownData) return;
|
if (!rundownData) return;
|
||||||
|
|
||||||
// get list of rundown with only ontime events
|
// get list of rundown with only ontime events
|
||||||
const events: OntimeEvent[] = [];
|
const eventIds: EntryId[] = [];
|
||||||
rundownData.order.forEach((eventId) => {
|
rundownData.flatOrder.forEach((eventId) => {
|
||||||
const event = rundownData.entries[eventId];
|
const event = rundownData.entries[eventId];
|
||||||
if (isOntimeEvent(event)) {
|
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);
|
const end = anchoredIndex === null ? index : Math.max(anchoredIndex, index + 1);
|
||||||
|
|
||||||
// create new set with range of ids from start to end
|
// 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({
|
return set({
|
||||||
selectedEvents: new Set([...selectedEvents, ...selectedEventIds]),
|
selectedEvents: new Set([...selectedEvents, ...selectedEventIds]),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useTableNav } from '@table-nav/react';
|
|||||||
import { ColumnDef, getCoreRowModel, useReactTable } from '@tanstack/react-table';
|
import { ColumnDef, getCoreRowModel, useReactTable } from '@tanstack/react-table';
|
||||||
import { isOntimeEvent, MaybeString, OntimeEntry, OntimeEvent, TimeField } from 'ontime-types';
|
import { isOntimeEvent, MaybeString, OntimeEntry, OntimeEvent, TimeField } from 'ontime-types';
|
||||||
|
|
||||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||||
import useFollowComponent from '../../../common/hooks/useFollowComponent';
|
import useFollowComponent from '../../../common/hooks/useFollowComponent';
|
||||||
import { useCuesheetOptions } from '../cuesheet.options';
|
import { useCuesheetOptions } from '../cuesheet.options';
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ interface CuesheetTableProps {
|
|||||||
export default function CuesheetTable(props: CuesheetTableProps) {
|
export default function CuesheetTable(props: CuesheetTableProps) {
|
||||||
const { data, columns, showModal } = props;
|
const { data, columns, showModal } = props;
|
||||||
|
|
||||||
const { updateEvent, updateTimer } = useEventAction();
|
const { updateEntry, updateTimer } = useEntryActions();
|
||||||
const { followSelected, showDelayedTimes, hideTableSeconds } = useCuesheetOptions();
|
const { followSelected, showDelayedTimes, hideTableSeconds } = useCuesheetOptions();
|
||||||
const { columnVisibility, columnOrder, columnSizing, resetColumnOrder, setColumnVisibility, setColumnSizing } =
|
const { columnVisibility, columnOrder, columnSizing, resetColumnOrder, setColumnVisibility, setColumnSizing } =
|
||||||
useColumnManager(columns);
|
useColumnManager(columns);
|
||||||
@@ -64,11 +64,11 @@ export default function CuesheetTable(props: CuesheetTableProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isCustom) {
|
if (isCustom) {
|
||||||
updateEvent({ id: event.id, custom: { [accessor]: payload } });
|
updateEntry({ id: event.id, custom: { [accessor]: payload } });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEvent({ id: event.id, [accessor]: payload });
|
updateEntry({ id: event.id, [accessor]: payload });
|
||||||
},
|
},
|
||||||
handleUpdateTimer: (eventId: string, field: TimeField, payload) => {
|
handleUpdateTimer: (eventId: string, field: TimeField, payload) => {
|
||||||
// the timer element already contains logic to avoid submitting a unchanged value
|
// the timer element already contains logic to avoid submitting a unchanged value
|
||||||
|
|||||||
+9
-9
@@ -2,7 +2,7 @@ import { IoAdd, IoArrowDown, IoArrowUp, IoDuplicateOutline, IoOptions, IoTrash }
|
|||||||
import { MenuDivider, MenuItem, MenuList } from '@chakra-ui/react';
|
import { MenuDivider, MenuItem, MenuList } from '@chakra-ui/react';
|
||||||
import { isOntimeEvent, SupportedEvent } from 'ontime-types';
|
import { isOntimeEvent, SupportedEvent } from 'ontime-types';
|
||||||
|
|
||||||
import { useEventAction } from '../../../../common/hooks/useEventAction';
|
import { useEntryActions } from '../../../../common/hooks/useEntryAction';
|
||||||
import { cloneEvent } from '../../../../common/utils/eventsManager';
|
import { cloneEvent } from '../../../../common/utils/eventsManager';
|
||||||
|
|
||||||
interface CuesheetTableMenuActionsProps {
|
interface CuesheetTableMenuActionsProps {
|
||||||
@@ -13,17 +13,17 @@ interface CuesheetTableMenuActionsProps {
|
|||||||
|
|
||||||
export default function CuesheetTableMenuActions(props: CuesheetTableMenuActionsProps) {
|
export default function CuesheetTableMenuActions(props: CuesheetTableMenuActionsProps) {
|
||||||
const { eventId, entryIndex, showModal } = props;
|
const { eventId, entryIndex, showModal } = props;
|
||||||
const { addEvent, getEventById, reorderEvent, deleteEvent } = useEventAction();
|
const { addEntry, getEntryById, reorderEntry, deleteEntry } = useEntryActions();
|
||||||
|
|
||||||
const handleCloneEvent = () => {
|
const handleCloneEvent = () => {
|
||||||
const currentEvent = getEventById(eventId);
|
const currentEvent = getEntryById(eventId);
|
||||||
if (!currentEvent || !isOntimeEvent(currentEvent)) {
|
if (!currentEvent || !isOntimeEvent(currentEvent)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newEvent = cloneEvent(currentEvent);
|
const newEvent = cloneEvent(currentEvent);
|
||||||
try {
|
try {
|
||||||
addEvent(newEvent, { after: eventId });
|
addEntry(newEvent, { after: eventId });
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
// we do not handle errors here
|
// we do not handle errors here
|
||||||
}
|
}
|
||||||
@@ -35,10 +35,10 @@ export default function CuesheetTableMenuActions(props: CuesheetTableMenuActions
|
|||||||
Edit ...
|
Edit ...
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<MenuItem icon={<IoAdd />} onClick={() => addEvent({ type: SupportedEvent.Event }, { before: eventId })}>
|
<MenuItem icon={<IoAdd />} onClick={() => addEntry({ type: SupportedEvent.Event }, { before: eventId })}>
|
||||||
Add event above
|
Add event above
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<IoAdd />} onClick={() => addEvent({ type: SupportedEvent.Event }, { after: eventId })}>
|
<MenuItem icon={<IoAdd />} onClick={() => addEntry({ type: SupportedEvent.Event }, { after: eventId })}>
|
||||||
Add event below
|
Add event below
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<IoDuplicateOutline />} onClick={handleCloneEvent}>
|
<MenuItem icon={<IoDuplicateOutline />} onClick={handleCloneEvent}>
|
||||||
@@ -48,14 +48,14 @@ export default function CuesheetTableMenuActions(props: CuesheetTableMenuActions
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
isDisabled={entryIndex < 1}
|
isDisabled={entryIndex < 1}
|
||||||
icon={<IoArrowUp />}
|
icon={<IoArrowUp />}
|
||||||
onClick={() => reorderEvent(eventId, entryIndex, entryIndex - 1)}
|
onClick={() => reorderEntry(eventId, entryIndex, entryIndex - 1)}
|
||||||
>
|
>
|
||||||
Move up
|
Move up
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<IoArrowDown />} onClick={() => reorderEvent(eventId, entryIndex, entryIndex + 1)}>
|
<MenuItem icon={<IoArrowDown />} onClick={() => reorderEntry(eventId, entryIndex, entryIndex + 1)}>
|
||||||
Move down
|
Move down
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<IoTrash />} onClick={() => deleteEvent([eventId])}>
|
<MenuItem icon={<IoTrash />} onClick={() => deleteEntry([eventId])}>
|
||||||
Delete
|
Delete
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import {
|
|||||||
addEvent,
|
addEvent,
|
||||||
applyDelay,
|
applyDelay,
|
||||||
batchEditEvents,
|
batchEditEvents,
|
||||||
deleteAllEvents,
|
deleteAllEntries,
|
||||||
deleteEvent,
|
deleteEvent,
|
||||||
editEvent,
|
editEvent,
|
||||||
reorderEvent,
|
reorderEntry,
|
||||||
swapEvents,
|
swapEvents,
|
||||||
} from '../../services/rundown-service/RundownService.js';
|
} from '../../services/rundown-service/RundownService.js';
|
||||||
import { getEventWithId, getCurrentRundown } from '../../services/rundown-service/rundownUtils.js';
|
import { getEntryWithId, getCurrentRundown } from '../../services/rundown-service/rundownUtils.js';
|
||||||
|
|
||||||
export async function rundownGetAll(_req: Request, res: Response<ProjectRundownsList>) {
|
export async function rundownGetAll(_req: Request, res: Response<ProjectRundownsList>) {
|
||||||
const rundown = getCurrentRundown();
|
const rundown = getCurrentRundown();
|
||||||
@@ -30,7 +30,7 @@ export async function rundownGetById(req: Request, res: Response<OntimeEntry | E
|
|||||||
const { eventId } = req.params;
|
const { eventId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const event = getEventWithId(eventId);
|
const event = getEntryWithId(eventId);
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
res.status(404).send({ message: 'Event not found' });
|
res.status(404).send({ message: 'Event not found' });
|
||||||
@@ -93,7 +93,7 @@ export async function rundownReorder(req: Request, res: Response<OntimeEntry | E
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { eventId, from, to } = req.body;
|
const { eventId, from, to } = req.body;
|
||||||
const event = await reorderEvent(eventId, from, to);
|
const event = await reorderEntry(eventId, from, to);
|
||||||
res.status(200).send(event.newEvent);
|
res.status(200).send(event.newEvent);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = getErrorMessage(error);
|
const message = getErrorMessage(error);
|
||||||
@@ -128,7 +128,7 @@ export async function rundownApplyDelay(req: Request, res: Response<MessageRespo
|
|||||||
|
|
||||||
export async function rundownDelete(_req: Request, res: Response<MessageResponse | ErrorResponse>) {
|
export async function rundownDelete(_req: Request, res: Response<MessageResponse | ErrorResponse>) {
|
||||||
try {
|
try {
|
||||||
await deleteAllEvents();
|
await deleteAllEntries();
|
||||||
res.status(204).send({ message: 'All events deleted' });
|
res.status(204).send({ message: 'All events deleted' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = getErrorMessage(error);
|
const message = getErrorMessage(error);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { EndAction, OntimeEvent, TimerType, isKeyOfType, isOntimeEvent } from 'o
|
|||||||
import { MILLIS_PER_SECOND, maxDuration } from 'ontime-utils';
|
import { MILLIS_PER_SECOND, maxDuration } from 'ontime-utils';
|
||||||
|
|
||||||
import { editEvent } from '../services/rundown-service/RundownService.js';
|
import { editEvent } from '../services/rundown-service/RundownService.js';
|
||||||
import { getEventWithId } from '../services/rundown-service/rundownUtils.js';
|
import { getEntryWithId } from '../services/rundown-service/rundownUtils.js';
|
||||||
import { coerceBoolean, coerceColour, coerceEnum, coerceNumber, coerceString } from '../utils/coerceType.js';
|
import { coerceBoolean, coerceColour, coerceEnum, coerceNumber, coerceString } from '../utils/coerceType.js';
|
||||||
import { getDataProvider } from '../classes/data-provider/DataProvider.js';
|
import { getDataProvider } from '../classes/data-provider/DataProvider.js';
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ export function parseProperty(property: string, value: unknown) {
|
|||||||
* @param {Partial<OntimeEvent>} patchEvent
|
* @param {Partial<OntimeEvent>} patchEvent
|
||||||
*/
|
*/
|
||||||
export function updateEvent(patchEvent: Partial<OntimeEvent> & { id: string }) {
|
export function updateEvent(patchEvent: Partial<OntimeEvent> & { id: string }) {
|
||||||
const event = getEventWithId(patchEvent?.id ?? '');
|
const event = getEntryWithId(patchEvent?.id ?? '');
|
||||||
if (!event) {
|
if (!event) {
|
||||||
throw new Error(`Event with ID ${patchEvent?.id} not found`);
|
throw new Error(`Event with ID ${patchEvent?.id} not found`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,9 +126,9 @@ export async function deleteEvent(eventIds: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deletes all events in database
|
* deletes all entries in database
|
||||||
*/
|
*/
|
||||||
export async function deleteAllEvents() {
|
export async function deleteAllEntries() {
|
||||||
const scopedMutation = cache.mutateCache(cache.removeAll);
|
const scopedMutation = cache.mutateCache(cache.removeAll);
|
||||||
await scopedMutation({});
|
await scopedMutation({});
|
||||||
|
|
||||||
@@ -182,12 +182,12 @@ export async function batchEditEvents(ids: string[], data: Partial<OntimeEvent>)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reorders a given event
|
* reorders a given entry
|
||||||
* @param {string} eventId - ID of event from, for sanity check
|
* @param {string} eventId - ID of event from, for sanity check
|
||||||
* @param {number} from - index of event from
|
* @param {number} from - index of event from
|
||||||
* @param {number} to - index of event to
|
* @param {number} to - index of event to
|
||||||
*/
|
*/
|
||||||
export async function reorderEvent(eventId: string, from: number, to: number) {
|
export async function reorderEntry(eventId: EntryId, from: number, to: number) {
|
||||||
const scopedMutation = cache.mutateCache(cache.reorder);
|
const scopedMutation = cache.mutateCache(cache.reorder);
|
||||||
const reorderedItem = await scopedMutation({ eventId, from, to });
|
const reorderedItem = await scopedMutation({ eventId, from, to });
|
||||||
|
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ export function getEventAtIndex(eventIndex: number): OntimeEvent | undefined {
|
|||||||
/**
|
/**
|
||||||
* returns first event that matches a given ID
|
* returns first event that matches a given ID
|
||||||
*/
|
*/
|
||||||
export function getEventWithId(eventId: string): OntimeEntry | undefined {
|
export function getEntryWithId(entryId: EntryId): OntimeEntry | undefined {
|
||||||
const { entries } = getCurrentRundown();
|
const { entries } = getCurrentRundown();
|
||||||
return entries[eventId];
|
return entries[entryId];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,7 +71,7 @@ export function getEventWithId(eventId: string): OntimeEntry | undefined {
|
|||||||
export function getFirstPlayable(playableOrder: EntryId[]): PlayableEvent | undefined {
|
export function getFirstPlayable(playableOrder: EntryId[]): PlayableEvent | undefined {
|
||||||
const firstEventId = playableOrder.at(0);
|
const firstEventId = playableOrder.at(0);
|
||||||
if (!firstEventId) return;
|
if (!firstEventId) return;
|
||||||
return getEventWithId(firstEventId) as PlayableEvent | undefined;
|
return getEntryWithId(firstEventId) as PlayableEvent | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +84,7 @@ export function getNextEventWithCue(targetCue: string, currentEventIndex = 0): O
|
|||||||
|
|
||||||
for (let i = currentEventIndex; i < playableEventsOrder.length; i++) {
|
for (let i = currentEventIndex; i < playableEventsOrder.length; i++) {
|
||||||
const eventId = playableEventsOrder[i];
|
const eventId = playableEventsOrder[i];
|
||||||
const event = getEventWithId(eventId) as PlayableEvent | undefined;
|
const event = getEntryWithId(eventId) as PlayableEvent | undefined;
|
||||||
if (event?.cue.toLowerCase() === lowerCaseCue) {
|
if (event?.cue.toLowerCase() === lowerCaseCue) {
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ export function findPrevious(currentEventId?: string): OntimeEvent | undefined {
|
|||||||
return getFirstPlayable(playableEventsOrder);
|
return getFirstPlayable(playableEventsOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getEventWithId(previousEventId) as PlayableEvent | undefined;
|
return getEntryWithId(previousEventId) as PlayableEvent | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,7 +140,7 @@ export function findNext(currentEventId?: string): PlayableEvent | undefined {
|
|||||||
return getFirstPlayable(playableEventsOrder);
|
return getFirstPlayable(playableEventsOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getEventWithId(nextEventId) as PlayableEvent | undefined;
|
return getEntryWithId(nextEventId) as PlayableEvent | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterTimedEvents(rundown: Rundown, timedEventOrder: EntryId[]): OntimeEvent[] {
|
export function filterTimedEvents(rundown: Rundown, timedEventOrder: EntryId[]): OntimeEvent[] {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
findPrevious,
|
findPrevious,
|
||||||
getEventAtIndex,
|
getEventAtIndex,
|
||||||
getNextEventWithCue,
|
getNextEventWithCue,
|
||||||
getEventWithId,
|
getEntryWithId,
|
||||||
getCurrentRundown,
|
getCurrentRundown,
|
||||||
getTimedEvents,
|
getTimedEvents,
|
||||||
getRundownData,
|
getRundownData,
|
||||||
@@ -258,7 +258,7 @@ class RuntimeService {
|
|||||||
if (safeOption || eventInMemory) {
|
if (safeOption || eventInMemory) {
|
||||||
if (state.eventNow !== null) {
|
if (state.eventNow !== null) {
|
||||||
// load stuff again, but keep running if our events still exist
|
// load stuff again, but keep running if our events still exist
|
||||||
const eventNow = getEventWithId(state.eventNow.id);
|
const eventNow = getEntryWithId(state.eventNow.id);
|
||||||
if (!isOntimeEvent(eventNow) || !isPlayableEvent(eventNow)) {
|
if (!isOntimeEvent(eventNow) || !isPlayableEvent(eventNow)) {
|
||||||
// maybe the event was deleted or the skip state was changed
|
// maybe the event was deleted or the skip state was changed
|
||||||
runtimeState.stop();
|
runtimeState.stop();
|
||||||
@@ -323,7 +323,7 @@ class RuntimeService {
|
|||||||
*/
|
*/
|
||||||
@broadcastResult
|
@broadcastResult
|
||||||
public startById(eventId: string): boolean {
|
public startById(eventId: string): boolean {
|
||||||
const event = getEventWithId(eventId);
|
const event = getEntryWithId(eventId);
|
||||||
if (!event || !isOntimeEvent(event)) {
|
if (!event || !isOntimeEvent(event)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ class RuntimeService {
|
|||||||
*/
|
*/
|
||||||
@broadcastResult
|
@broadcastResult
|
||||||
public loadById(eventId: string): boolean {
|
public loadById(eventId: string): boolean {
|
||||||
const event = getEventWithId(eventId);
|
const event = getEntryWithId(eventId);
|
||||||
if (!event || !isOntimeEvent(event)) {
|
if (!event || !isOntimeEvent(event)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -654,7 +654,7 @@ class RuntimeService {
|
|||||||
|
|
||||||
// the db would have to change for the event not to exist
|
// the db would have to change for the event not to exist
|
||||||
// we do not know the reason for the crash, so we check anyway
|
// we do not know the reason for the crash, so we check anyway
|
||||||
const event = getEventWithId(selectedEventId);
|
const event = getEntryWithId(selectedEventId);
|
||||||
if (!isOntimeEvent(event) || !isPlayableEvent(event)) {
|
if (!isOntimeEvent(event) || !isPlayableEvent(event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user