mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 15:09:10 +00:00
Fix integration api (#1866)
* allow change api to set flag and countToEnd * fix: custom fields can be uppercase * check that prop exists and add target duration for group
This commit is contained in:
committed by
GitHub
parent
15f3b9625c
commit
cee3c9c070
@@ -24,6 +24,7 @@ import { throttle } from '../utils/throttle.js';
|
|||||||
import { coerceEnum } from '../utils/coerceType.js';
|
import { coerceEnum } from '../utils/coerceType.js';
|
||||||
import { editEntry } from '../api-data/rundown/rundown.service.js';
|
import { editEntry } from '../api-data/rundown/rundown.service.js';
|
||||||
import { willCauseRegeneration } from '../api-data/rundown/rundown.utils.js';
|
import { willCauseRegeneration } from '../api-data/rundown/rundown.utils.js';
|
||||||
|
import { getCurrentRundown } from '../api-data/rundown/rundown.dao.js';
|
||||||
|
|
||||||
const throttledEditEvent = throttle(editEntry, 20);
|
const throttledEditEvent = throttle(editEntry, 20);
|
||||||
let lastRequest: Date | null = null;
|
let lastRequest: Date | null = null;
|
||||||
@@ -63,32 +64,39 @@ const actionHandlers: Record<ApiActionTag, ActionHandler> = {
|
|||||||
throw new Error('Missing Event ID');
|
throw new Error('Missing Event ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { entries } = getCurrentRundown();
|
||||||
|
|
||||||
|
const targetEntry = entries[id];
|
||||||
|
if (!targetEntry) {
|
||||||
|
throw new Error('ID do not exits in rundown');
|
||||||
|
}
|
||||||
|
|
||||||
const data = payload[id as keyof typeof payload];
|
const data = payload[id as keyof typeof payload];
|
||||||
const patchEvent: PatchWithId<OntimeEvent> = { id };
|
const patchEntry: PatchWithId<OntimeEvent> = { id }; // It is not necessarily an event could also be milestone or group but we don't need to track that in the typing here
|
||||||
|
|
||||||
let shouldThrottle = false;
|
let shouldThrottle = false;
|
||||||
|
|
||||||
Object.entries(data).forEach(([property, value]) => {
|
Object.entries(data).forEach(([property, value]) => {
|
||||||
if (typeof property !== 'string' || value === undefined) {
|
if (typeof property !== 'string' || value === undefined || !(property in targetEntry)) {
|
||||||
throw new Error('Invalid property or value');
|
throw new Error('Invalid property or value');
|
||||||
}
|
}
|
||||||
// parseProperty is async because of the data lock
|
// parseProperty is async because of the data lock
|
||||||
const newObjectProperty = parseProperty(property, value);
|
const newObjectProperty = parseProperty(property, value);
|
||||||
const key = Object.keys(newObjectProperty)[0] as keyof OntimeEvent;
|
const key = Object.keys(newObjectProperty)[0];
|
||||||
shouldThrottle = shouldThrottle || willCauseRegeneration(key);
|
shouldThrottle = shouldThrottle || willCauseRegeneration(key);
|
||||||
if (patchEvent.custom && newObjectProperty.custom) {
|
if (patchEntry.custom && newObjectProperty.custom) {
|
||||||
Object.assign(patchEvent.custom, newObjectProperty.custom);
|
Object.assign(patchEntry.custom, newObjectProperty.custom);
|
||||||
} else {
|
} else {
|
||||||
Object.assign(patchEvent, newObjectProperty);
|
Object.assign(patchEntry, newObjectProperty);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (shouldThrottle) {
|
if (shouldThrottle) {
|
||||||
if (throttledEditEvent(patchEvent)) {
|
if (throttledEditEvent(patchEntry)) {
|
||||||
return { payload: 'throttled' };
|
return { payload: 'throttled' };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
editEntry(patchEvent).catch((_error) => {
|
editEntry(patchEntry).catch((_error) => {
|
||||||
/** No error handling */
|
/** No error handling */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ function clampDuration(value: number): number {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const propertyConversion = {
|
const propertyConversion: Record<string, (value: unknown) => unknown> = {
|
||||||
title: coerceString,
|
title: coerceString,
|
||||||
note: coerceString,
|
note: coerceString,
|
||||||
cue: coerceString,
|
cue: coerceString,
|
||||||
|
|
||||||
skip: coerceBoolean,
|
skip: coerceBoolean,
|
||||||
|
flag: coerceBoolean,
|
||||||
|
countToEnd: coerceBoolean,
|
||||||
|
|
||||||
colour: coerceColour,
|
colour: coerceColour,
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ const propertyConversion = {
|
|||||||
linkStart: coerceBoolean,
|
linkStart: coerceBoolean,
|
||||||
timeStrategy: (value: unknown) => coerceEnum<TimeStrategy>(value, TimeStrategy),
|
timeStrategy: (value: unknown) => coerceEnum<TimeStrategy>(value, TimeStrategy),
|
||||||
|
|
||||||
|
targetDuration: (value: unknown) => clampDuration(coerceNumber(value)), // only exist in the group
|
||||||
duration: (value: unknown) => clampDuration(coerceNumber(value)),
|
duration: (value: unknown) => clampDuration(coerceNumber(value)),
|
||||||
timeStart: (value: unknown) => clampDuration(coerceNumber(value)),
|
timeStart: (value: unknown) => clampDuration(coerceNumber(value)),
|
||||||
timeEnd: (value: unknown) => clampDuration(coerceNumber(value)),
|
timeEnd: (value: unknown) => clampDuration(coerceNumber(value)),
|
||||||
@@ -43,7 +46,7 @@ const propertyConversion = {
|
|||||||
|
|
||||||
export function parseProperty(property: string, value: unknown) {
|
export function parseProperty(property: string, value: unknown) {
|
||||||
if (property.startsWith('custom:')) {
|
if (property.startsWith('custom:')) {
|
||||||
const customKey = property.split(':')[1].toLocaleLowerCase(); // all custom fields keys are lowercase
|
const customKey = property.split(':')[1];
|
||||||
const customFields = getDataProvider().getCustomFields();
|
const customFields = getDataProvider().getCustomFields();
|
||||||
if (!(customKey in customFields)) {
|
if (!(customKey in customFields)) {
|
||||||
throw new Error(`Custom field ${customKey} not found`);
|
throw new Error(`Custom field ${customKey} not found`);
|
||||||
|
|||||||
Reference in New Issue
Block a user